Om
form.cpp
Go to the documentation of this file.
1 
15 #ifndef Om_Language_Form_
16 
17  #include "om/language/form.hpp"
18 
19 #else
20 
21 // MARK: - Om::Language::Form
22 
23  #define Type_ \
24  Om::Language::Form
25 
26 // MARK: public (non-static)
27 
28 inline Type_::Form():
29 thisOperator(),
30 thisOperandDeque() {}
31 
32 inline bool Type_::BackGiveTerm(Consumer & theConsumer) {
33  if (
34  this->thisOperandDeque.empty()
35  ) {
36  assert(
37  !this->thisOperator.IsEmpty()
38  );
39  this->thisOperator.GiveElements(theConsumer);
40  assert(
41  this->thisOperator.IsEmpty()
42  );
43  return true;
44  }
45  this->thisOperandDeque.back().GiveElements(theConsumer);
46  this->thisOperandDeque.pop_back();
47  return this->IsEmpty();
48 }
49 
50 inline bool Type_::BackPopTerm() {
51  if (
52  this->thisOperandDeque.empty()
53  ) {
54  assert(
55  !this->thisOperator.IsEmpty()
56  );
57  Operator().Swap(this->thisOperator);
58  return true;
59  }
60  this->thisOperandDeque.pop_back();
61  return this->IsEmpty();
62 }
63 
64 template <typename TheOperand>
65 inline void Type_::BackTakeOperand(TheOperand & theOperand) {
66  this->thisOperandDeque.push_back(
67  Operand()
68  );
69  this->thisOperandDeque.back().Take(theOperand);
70 }
71 
72 template <typename TheProducer>
73 inline void Type_::BackTakeQuotedProducer(TheProducer & theProducer) {
74  this->thisOperandDeque.push_back(
75  Operand()
76  );
77  this->thisOperandDeque.back().SetProgram(
78  theProducer.GiveProgram()
79  );
80 }
81 
82 inline bool Type_::FrontGiveTerm(Consumer & theConsumer) {
83  if (
84  this->thisOperator.IsEmpty()
85  ) {
86  assert(
87  !this->thisOperandDeque.empty()
88  );
89  this->thisOperandDeque.front().GiveElements(theConsumer);
90  this->thisOperandDeque.pop_front();
91  } else {
92  this->thisOperator.GiveElements(theConsumer);
93  assert(
94  this->thisOperator.IsEmpty()
95  );
96  }
97  return this->thisOperandDeque.empty();
98 }
99 
100 inline bool Type_::FrontPopTerm() {
101  if (
102  this->thisOperator.IsEmpty()
103  ) {
104  assert(
105  !this->thisOperandDeque.empty()
106  );
107  this->thisOperandDeque.pop_front();
108  } else {
109  Operator().Swap(this->thisOperator);
110  assert(
111  this->thisOperator.IsEmpty()
112  );
113  }
114  return this->thisOperandDeque.empty();
115 }
116 
117 template <typename TheOperand>
118 inline void Type_::FrontTakeOperand(TheOperand & theOperand) {
119  this->thisOperandDeque.push_front(
120  Operand()
121  );
122  this->thisOperandDeque.front().Take(theOperand);
123 }
124 
125 template <typename TheProducer>
126 inline void Type_::FrontTakeQuotedProducer(TheProducer & theProducer) {
127  this->thisOperandDeque.push_front(
128  Operand()
129  );
130  this->thisOperandDeque.front().SetProgram(
131  theProducer.GiveProgram()
132  );
133 }
134 
135 inline Om::Language::Operator const & Type_::GetOperator() const {
136  return this->thisOperator;
137 }
138 
139 inline void Type_::GiveElements(Consumer & theConsumer) {
140  this->GiveElements<OperandDeque::iterator>(
141  *this,
142  theConsumer
143  );
144  this->thisOperandDeque.clear();
145 }
146 
147 inline void Type_::GiveElements(Consumer & theConsumer) const {
148  this->GiveElements<OperandDeque::const_iterator>(
149  *this,
150  theConsumer
151  );
152 }
153 
154 inline bool Type_::IsEmpty() const {
155  return (
156  this->thisOperator.IsEmpty() &&
157  this->thisOperandDeque.empty()
158  );
159 }
160 
161 inline void Type_::Swap(Form & theForm) {
162  this->thisOperator.Swap(theForm.thisOperator);
163  this->thisOperandDeque.swap(theForm.thisOperandDeque);
164 }
165 
166 template <typename TheOperator>
167 inline void Type_::TakeOperator(TheOperator & theOperator) {
168  assert(
169  !theOperator.IsEmpty()
170  );
171  this->thisOperator.Take(theOperator);
172 }
173 
174 // MARK: private (static)
175 
176 template <
177  typename TheOperandIterator,
178  typename TheForm
179 >
180 inline void Type_::GiveElements(
181  TheForm & theForm,
182  Consumer & theConsumer
183 ) {
184  assert(
185  !theForm.IsEmpty()
186  );
187  if (
188  !theForm.thisOperator.IsEmpty()
189  ) {
190  theConsumer.TakeElement(theForm.thisOperator);
191  }
192  TheOperandIterator const theEnd = theForm.thisOperandDeque.end();
193  for (
194  TheOperandIterator theCurrent = theForm.thisOperandDeque.begin();
195  theEnd != theCurrent;
196  ++theCurrent
197  ) {
198  theConsumer.TakeElement(*theCurrent);
199  }
200 }
201 
202  #undef Type_
203 
204 // MARK: - Om::Language::Form::ElementRange
205 
206  #define Type_ \
207  Om::Language::Form::ElementRange
208 
209 // MARK: public (non-static)
210 
211 inline Type_::ElementRange(Form const & theForm):
212 thisOperandIterator(
213  theForm.thisOperandDeque.begin()
214 ),
215 thisOperandEnd(
216  theForm.thisOperandDeque.end()
217 ),
218 thisElement(&theForm.thisOperator) {
219  if (
220  theForm.thisOperator.IsEmpty()
221  ) {
222  assert(this->thisOperandEnd != this->thisOperandIterator);
223  this->thisElement = &*this->thisOperandIterator++;
224  }
225 }
226 
227 inline bool Type_::operator !() const {
228  return !this->thisElement;
229 }
230 
231 inline Om::Language::Element const & Type_::operator *() const {
232  assert(this->thisElement);
233  return *this->thisElement;
234 }
235 
236 inline bool Type_::Equals(ElementRange const & theElementRange) const {
237  return this->thisElement == theElementRange.thisElement;
238 }
239 
240 inline void Type_::End() {
241  this->thisElement = 0;
242 }
243 
244 inline void Type_::Pop() {
245  assert(this->thisElement);
246  this->thisElement = (
247  this->thisOperandEnd == this->thisOperandIterator ?
248  0 :
249  &*this->thisOperandIterator++
250  );
251 }
252 
253 // MARK: - Om::Language::
254 
255 inline bool Om::Language::operator ==(
256  Type_ const & theFirst,
257  Type_ const & theSecond
258 ) {
259  return theFirst.Equals(theSecond);
260 }
261 
262 inline bool Om::Language::operator !=(
263  Type_ const & theFirst,
264  Type_ const & theSecond
265 ) {
266  return !theFirst.Equals(theSecond);
267 }
268 
269  #undef Type_
270 
271 // MARK: - Om::Language::Form::OperandRange
272 
273  #define Type_ \
274  Om::Language::Form::OperandRange
275 
276 // MARK: public (non-static)
277 
278 inline Type_<Om::Language::Operand>::OperandRange(Form & theForm):
279 Om::Source::CollectionFrontSource<
280  Operand,
281  OperandDeque::iterator
282 >(theForm.thisOperandDeque) {}
283 
284 inline Type_<Om::Language::Operand const>::OperandRange(Form const & theForm):
285 Om::Source::CollectionFrontSource<
286  Operand const,
287  OperandDeque::const_iterator
288 >(theForm.thisOperandDeque) {}
289 
290  #undef Type_
291 
292 // MARK: - boost::
293 
294 template <>
295 inline void boost::swap(
296  Om::Language::Form & theFirst,
297  Om::Language::Form & theSecond
298 ) {
299  theFirst.Swap(theSecond);
300 }
301 
302 #endif
A Program that contains a single elemental item (or none, when IsEmpty() returns true).
Definition: element.hpp:33
An Operator (which may be empty), followed by zero or more Operand instances.
Definition: form.hpp:33
void Swap(Form &)
The Operator implementation.
Definition: operator.hpp:60
Om header file.
bool operator!=(DefaultAtom< TheImplementation > const &, DefaultAtom< TheImplementation > const &)
bool operator==(DefaultAtom< TheImplementation > const &, DefaultAtom< TheImplementation > const &)
The Om library.
Definition: code_point.hpp:26
void swap(Om::Language::Expression &, Om::Language::Expression &)