Om
inject_operation.cpp
Go to the documentation of this file.
1 
15 #ifndef Om_Language_Operation_InjectOperation_
16 
18 
19  #ifdef Om_Macro_Test_
20 
21  #ifndef Om_Macro_Precompilation_
22 
23  #include "boost/test/unit_test.hpp"
24 
25  #endif
26 
27 namespace Om {
28 
29  namespace Language {
30 
31  namespace Operation {
32 
33  BOOST_AUTO_TEST_SUITE(InjectOperationTest)
34 
35  BOOST_AUTO_TEST_CASE(DefinitionTest) {
36  BOOST_CHECK_EQUAL(
37  "{inject}",
38  System::Get().Evaluate("drop find {inject} system")
39  );
40  }
41 
42  BOOST_AUTO_TEST_CASE(GeneralTest) {
43  BOOST_CHECK_EQUAL(
44  (
45  "{"
46  "{"
47  "a{{A}}\n"
48  "b{{B}}\n"
49  "c{{C}}"
50  "}"
51  "}{D}{E}"
52  ),
53  System::Get().Evaluate("inject {quote} {fill {a b{{B}} c}} {A} {C} {D} {E}")
54  );
55 
56  BOOST_CHECK_EQUAL(
57  (
58  "{"
59  "{"
60  "a{A}\n"
61  "b{B}\n"
62  "c{A}\n"
63  "d{C}"
64  "}{C}"
65  "}{D}{E}"
66  ),
67  System::Get().Evaluate("inject {copy} {fill {a b{B} c d}} {A} {C} {D} {E}")
68  );
69 
70  BOOST_CHECK_EQUAL(
71  (
72  "inject{drop}{"
73  "fill{"
74  "a\n"
75  "b{B}\n"
76  "c\n"
77  "d"
78  "}"
79  "}"
80  ),
81  System::Get().Evaluate("inject {drop} {fill {a b{B} c d}} {A} {C} {D} {E}")
82  );
83  }
84 
85  BOOST_AUTO_TEST_CASE(EmptyInjectorTest) {
86  BOOST_CHECK_EQUAL(
87  (
88  "{"
89  "{"
90  "a{A}\n"
91  "b{B}\n"
92  "c{C}"
93  "}"
94  "}{D}{E}"
95  ),
96  System::Get().Evaluate("inject {} {fill {a b{B} c}} {A} {C} {D} {E}")
97  );
98  }
99 
100  BOOST_AUTO_TEST_CASE(EmptyOperationTest) {
101  BOOST_CHECK_EQUAL(
102  "{}{A}{C}{D}{E}",
103  System::Get().Evaluate("inject {quote} {} {A} {C} {D} {E}")
104  );
105  }
106 
107  BOOST_AUTO_TEST_CASE(FlushWithNoOperandsTest) {
108  BOOST_CHECK_EQUAL(
109  "inject",
110  System::Get().Evaluate("inject }")
111  );
112  }
113 
114  BOOST_AUTO_TEST_CASE(FlushWithOneOperandTest) {
115  BOOST_CHECK_EQUAL(
116  "inject{quote}",
117  System::Get().Evaluate("inject {quote} }")
118  );
119  }
120 
121  BOOST_AUTO_TEST_CASE(FlushWithTwoOperandsTest) {
122  BOOST_CHECK_EQUAL(
123  "inject{quote}{copy}",
124  System::Get().Evaluate("inject {quote} {copy} }")
125  );
126  }
127 
128  BOOST_AUTO_TEST_CASE(FlushWithMoreThanTwoOperandsTest) {
129  BOOST_CHECK_EQUAL(
130  (
131  "inject{quote}{"
132  "fill{"
133  "a{A}\n"
134  "b{B}\n"
135  "c"
136  "}"
137  "}"
138  ),
139  System::Get().Evaluate("inject {quote} {fill {a b c} {A} {B} }")
140  );
141  }
142 
143  BOOST_AUTO_TEST_SUITE_END()
144 
145  }
146 
147  }
148 
149 }
150 
151  #endif
152 
153 #else
154 
155  #ifndef Om_Macro_Precompilation_
156 
157  #include "boost/utility/in_place_factory.hpp"
158 
159  #endif
160 
161 // MARK: - Om::Language::Operation::InjectOperation
162 
163  #define Type_ \
164  Om::Language::Operation::InjectOperation
165 
166 // MARK: public (static)
167 
168 inline char const * Type_::GetName() {
170 }
171 
172 template <typename TheInjectOperation>
173 inline void Type_::GiveElements(
174  TheInjectOperation & theInjectOperation,
175  Consumer & theConsumer
176 ) {
177  theConsumer.TakeElement(
178  GetOperator()
179  );
180  if (theInjectOperation.thisScope) {
181  theConsumer.TakeQuotedElements(theInjectOperation.thisInjector);
182  if (
183  !theInjectOperation.thisScope->IsEmpty()
184  ) {
185  Expression theExpression;
186  theExpression.Take(theInjectOperation.thisOutput);
187  theInjectOperation.thisScope->GiveElements(theExpression);
188  theConsumer.TakeQuotedElements(theExpression);
189  }
190  }
191 }
192 
193 // MARK: public (non-static)
194 
195 inline Type_::InjectOperation():
196 thisInjector(),
197 thisOutput(),
198 thisScope() {}
199 
200 template <typename TheProducer>
201 inline bool Type_::TakeQuotedProducer(
202  Evaluation & theEvaluation,
203  TheProducer & theProducer
204 ) {
205  if (this->thisScope) {
206  if (
207  this->thisScope->IsEmpty()
208  ) {
209  theProducer.GiveElements(*this->thisScope);
210  } else {
211  {
212  Expression const & theInjector = this->thisInjector;
213  theInjector.GiveElements(*this->thisScope);
214  }
215  this->thisScope->TakeQuotedProducer(theProducer);
216  }
217 
218  if (
219  this->thisScope->IsEmpty()
220  ) {
221  theEvaluation.TakeQuotedProducer(this->thisOutput);
222  return true;
223  }
224  } else {
225  this->thisScope = boost::in_place(
226  boost::ref(this->thisOutput),
227  boost::ref(
228  theEvaluation.GetTranslator()
229  )
230  );
231  this->thisInjector.TakeElements(theProducer);
232  }
233  return false;
234 }
235 
236 template <typename TheOperand>
237 inline bool Type_::TakeOperand(
238  Evaluation & theEvaluation,
239  TheOperand & theOperand
240 ) {
241  assert(
242  !theOperand.IsEmpty()
243  );
244  return this->TakeQuotedProducer(
245  theEvaluation,
246  *theOperand.GetProgram()
247  );
248 }
249 
250  #undef Type_
251 
252 #endif
static System & Get()
Om header file.
#define Om_Language_Operation_InjectOperation_GetName_()
The Om library.
Definition: code_point.hpp:26