about summary refs log blame commit diff stats
path: root/033exclusive_container.cc
blob: 29a524c9cca7d0cb88a08c0495cb6bde383e5161 (plain) (tree)
quot;>(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>ingredient_names<span class="Delimiter">.</span>find<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))</span> != ingredient_names<span class="Delimiter">.</span>end<span class="Delimiter">())</span> result<span class="Delimiter">.</span>insert<span class="Delimiter">(</span>i<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Identifier">return</span> result<span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Comment">//: Sometimes you want to pass in two addresses, one pointing inside the</span> <span class="Comment">//: other. For example, you want to delete a node from a linked list. You</span> <span class="Comment">//: can't pass both pointers back out, because if a caller tries to make both</span> <span class="Comment">//: identical then you can't tell which value will be written on the way out.</span> <span class="Comment">//:</span> <span class="Comment">//: Experimental solution: just tell mu that one points inside the other.</span> <span class="Comment">//: This way we can return just one pointer as high up as necessary to capture</span> <span class="Comment">//: all modifications performed by a recipe.</span> <span class="Comment">//:</span> <span class="Comment">//: We'll see if we end up wanting to abuse /contained-in for other reasons.</span> <span class="Delimiter">:(scenarios transform)</span> <span class="Delimiter">:(scenario can_modify_contained_in_addresses)</span> container test-list [ <span class="Normal">value</span>:number <span class="Normal">next</span>:address:test-list ] def main [ local-scope <span class="Normal">p</span>:address:test-list<span class="Special"> &lt;- </span><span class="Normal">new</span> test-list:type foo p ] def foo p:address:test-list <span class="Delimiter">-&gt;</span> p:address:test-list [ local-scope load-ingredients <span class="Normal">p2</span>:address:test-list<span class="Special"> &lt;- </span>test-next p p<span class="Special"> &lt;- </span>test-remove p2<span class="Delimiter">,</span> p ] def test-next x:address:test-list <span class="Delimiter">-&gt;</span> y:address:test-list [ local-scope load-ingredients y<span class="Special"> &lt;- </span>get *x<span class="Delimiter">,</span> next:offset ] def test-remove x:address:test-list/contained-in:from<span class="Delimiter">,</span> from:address:test-list <span class="Delimiter">-&gt;</span> from:address:test-list [ local-scope load-ingredients *x<span class="Special"> &lt;- </span>put *x<span class="Delimiter">,</span> value:offset<span class="Delimiter">,</span> <span class="Constant">34</span> <span class="Comment"># can modify x</span> ] $error: <span class="Constant">0</span> <span class="Delimiter">:(before &quot;End Immutable Ingredients Special-cases&quot;)</span> <span class="Normal">if</span> <span class="Delimiter">(</span>has_property<span class="Delimiter">(</span>current_ingredient<span class="Delimiter">,</span> <span class="Constant">&quot;contained-in&quot;</span><span class="Delimiter">))</span> <span class="Delimiter">{</span> <span class="Normal">const</span> string_tree* tmp = property<span class="Delimiter">(</span>current_ingredient<span class="Delimiter">,</span> <span class="Constant">&quot;contained-in&quot;</span><span class="Delimiter">);</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!tmp<span class="Delimiter">-&gt;</span>atom || !is_present_in_ingredients<span class="Delimiter">(</span>caller<span class="Delimiter">,</span> tmp<span class="Delimiter">-&gt;</span>value<span class="Delimiter">)</span> || !is_present_in_products<span class="Delimiter">(</span>caller<span class="Delimiter">,</span> tmp<span class="Delimiter">-&gt;</span>value<span class="Delimiter">))</span> raise &lt;&lt; maybe<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;/contained-in can only point to another ingredient or product, but got '&quot;</span> &lt;&lt; to_string<span class="Delimiter">(</span>property<span class="Delimiter">(</span>current_ingredient<span class="Delimiter">,</span> <span class="Constant">&quot;contained-in&quot;</span><span class="Delimiter">))</span> &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> </pre> </body> </html> <!-- vim: set foldmethod=manual : -->