11#include < string>
22
33class SimpleList {
4+ private:
5+ // Структура узла
6+ struct Node {
7+ std::string val;
8+ Node* next;
9+ Node* prev;
10+
11+ Node (const std::string& st) : val(st), next(nullptr ), prev(nullptr ) {}
12+ Node (std::string&& st) : val(std::move(st)), next(nullptr ), prev(nullptr ) {}
13+ };
14+
15+ Node* head;
16+ size_t count;
17+
18+ // Создание узла
19+ template <typename T>
20+ Node* NewNode (T&& st) {
21+ return new Node (std::forward<T>(st));
22+ }
23+ // Вспомогательные методы
24+ void Link (Node* new_n, Node* before_n) {
25+ new_n->next = before_n;
26+ new_n->prev = before_n->prev ;
27+ before_n->prev ->next = new_n;
28+ before_n->prev = new_n;
29+ }
30+
31+ void Unlink (Node* n) {
32+ n->prev ->next = n->next ;
33+ n->next ->prev = n->prev ;
34+ delete n;
35+ }
36+
37+ public:
38+ // Конструктор по умолчанию
39+ SimpleList () : count(0 ) {
40+ head = new Node (std::string ());
41+ head->next = head;
42+ head->prev = head;
43+ }
44+
45+ // Копирующий конструктор
46+ SimpleList (const SimpleList& other) : SimpleList() {
47+ Node* current = other.head ->next ;
48+ while (current != other.head ) {
49+ PushBack (current->val );
50+ current = current->next ;
51+ }
52+ }
53+
54+ // Перемещающий конструктор
55+ SimpleList (SimpleList&& other) noexcept
56+ : head(other.head), count(other.count) {
57+ other.head = new Node (std::string ());
58+ other.head ->next = other.head ;
59+ other.head ->prev = other.head ;
60+ other.count = 0 ;
61+ }
62+
63+ // Деструктор
64+ ~SimpleList () {
65+ Clear ();
66+ delete head;
67+ }
68+
69+ // Копирующее присваивание
70+ SimpleList& operator =(const SimpleList& other) {
71+ if (this != &other) {
72+ // опробование метод copy-and-swap через внешнюю функцию Swap
73+ SimpleList temp (other);
74+ Swap (temp);
75+ }
76+ return *this ;
77+ }
78+
79+ // Перемещающее присваивание
80+ SimpleList& operator =(SimpleList&& other) noexcept {
81+ if (this != &other) {
82+ Clear ();
83+ delete head;
84+
85+ head = other.head ;
86+ count = other.count ;
87+
88+ other.head = new Node (std::string ());
89+ other.head ->next = other.head ;
90+ other.head ->prev = other.head ;
91+ other.count = 0 ;
92+ }
93+ return *this ;
94+ }
95+ // Методы
96+ void Swap (SimpleList& other) noexcept {
97+ std::swap (head, other.head );
98+ std::swap (count, other.count );
99+ }
100+
101+ size_t Size () const {
102+ return count;
103+ }
104+
105+ bool Empty () const {
106+ return count == 0 ;
107+ }
108+
109+ void PushBack (const std::string& value) {
110+ Node* new_node = NewNode (value);
111+ Link (new_node, head);
112+ ++count;
113+ }
114+ void PushBack (std::string&& value) {
115+ Node* new_node = NewNode (std::move (value));
116+ Link (new_node, head);
117+ ++count;
118+ }
119+
120+ void PushFront (const std::string& value) {
121+ Node* new_node = NewNode (value);
122+ Link (new_node, head->next );
123+ ++count;
124+ }
125+ void PushFront (std::string&& value) {
126+ Node* new_node = NewNode (std::move (value));
127+ Link (new_node, head->next );
128+ ++count;
129+ }
130+
131+
132+ void PopBack () {
133+ if (!Empty ()) {
134+ Unlink (head->prev );
135+ --count;
136+ }
137+ }
138+
139+ void PopFront () {
140+ if (!Empty ()) {
141+ Unlink (head->next );
142+ --count;
143+ }
144+ }
145+
146+ std::string& Front () {
147+ return head->next ->val ;
148+ }
149+ const std::string& Front () const {
150+ return head->next ->val ;
151+ }
152+
153+
154+ std::string& Back () {
155+ return head->prev ->val ;
156+ }
157+ const std::string& Back () const {
158+ return head->prev ->val ;
159+ }
160+
161+ void Clear () {
162+ while (!Empty ()) {
163+ PopFront ();
164+ }
165+ }
166+ };
167+
168+ // Внешняя функция Swap
169+ void Swap (SimpleList& lhs, SimpleList& rhs) noexcept {
170+ lhs.Swap (rhs);
4171
5172};
0 commit comments