]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | <?xml version="1.0" encoding="utf-8"?> |
2 | <!-- | |
3 | Copyright 2012 Eric Niebler | |
4 | ||
5 | Distributed under the Boost | |
6 | Software License, Version 1.0. (See accompanying | |
7 | file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
8 | --> | |
9 | <header name="boost/proto/domain.hpp"> | |
10 | <para> | |
11 | Contains definition of the <computeroutput><classname alt="boost::proto::domain">proto::domain<></classname> | |
12 | </computeroutput> class template and helpers for defining domains with a generator for customizing expression | |
13 | construction and a grammar for controlling operator overloading. | |
14 | </para> | |
15 | <namespace name="boost"> | |
16 | <namespace name="proto"> | |
17 | ||
18 | <!-- proto::domain<> --> | |
19 | <struct name="domain"> | |
20 | <template> | |
21 | <template-type-parameter name="Generator"> | |
22 | <default><classname>proto::default_generator</classname></default> | |
23 | </template-type-parameter> | |
24 | <template-type-parameter name="Grammar"> | |
25 | <default><classname>proto::_</classname></default> | |
26 | </template-type-parameter> | |
27 | <template-type-parameter name="Super"> | |
28 | <default><replaceable>unspecified</replaceable></default> | |
29 | </template-type-parameter> | |
30 | </template> | |
31 | <inherit><type>Generator</type></inherit> | |
32 | <purpose>For use in defining domain tags to be used with <computeroutput> | |
33 | <classname alt="proto::extends">proto::extends<></classname></computeroutput>, | |
34 | <computeroutput><macroname>BOOST_PROTO_EXTENDS</macroname>()</computeroutput> and | |
35 | <computeroutput><macroname>BOOST_PROTO_DEFINE_OPERATORS</macroname>()</computeroutput>. | |
36 | A <emphasis>domain</emphasis> associates an expression type with a <emphasis>generator</emphasis>, | |
37 | and optionally a <emphasis>grammar</emphasis>. It may also have a super-domain. Expressions | |
38 | in a sub-domain are interoperable (i.e. can be combined freely with) expressions in a | |
39 | super-domain. Finally, domains control how non-Proto objects are turned into Proto | |
40 | expressions and how they are combined to form larger Proto expressions. | |
41 | </purpose> | |
42 | <description> | |
43 | <para> | |
44 | The Generator parameter determines how new expressions in the domain are post-processed. Typically, a generator | |
45 | wraps all new expressions in a wrapper that imparts domain-specific behaviors to expressions within | |
46 | its domain. (See <computeroutput><classname alt="proto::extends">proto::extends<></classname></computeroutput>.) | |
47 | </para> | |
48 | <para> | |
49 | The Grammar parameter determines whether a given expression is valid within the domain, and automatically | |
50 | disables any operator overloads which would cause an invalid expression to be created. By default, | |
51 | the Grammar parameter defaults to the wildcard, <computeroutput><classname>proto::_</classname> | |
52 | </computeroutput>, which makes all expressions valid within the domain. | |
53 | </para> | |
54 | <para> | |
55 | The Super parameter declares the domain currently being defined to be a sub-domain of Super. An expression in | |
56 | a sub-domain can be freely combined with expressions in its super-domain (and <emphasis>its</emphasis> | |
57 | super-domain, etc.). | |
58 | </para> | |
59 | <para> | |
60 | Example: <programlisting> template<typename Expr> | |
61 | struct MyExpr; | |
62 | ||
63 | struct MyGrammar | |
64 | : <classname>proto::or_</classname>< <classname>proto::terminal</classname><_>, <classname>proto::plus</classname><MyGrammar, MyGrammar> > | |
65 | {}; | |
66 | ||
67 | // Define MyDomain, in which all expressions are | |
68 | // wrapped in MyExpr<> and only expressions that | |
69 | // conform to MyGrammar are allowed. | |
70 | struct MyDomain | |
71 | : <classname>proto::domain</classname><<classname>proto::generator</classname><MyExpr>, MyGrammar> | |
72 | {}; | |
73 | ||
74 | // Use MyDomain to define MyExpr | |
75 | template<typename Expr> | |
76 | struct MyExpr | |
77 | : <classname>proto::extends</classname><Expr, MyExpr<Expr>, MyDomain> | |
78 | { | |
79 | // ... | |
80 | }; | |
81 | </programlisting> | |
82 | </para> | |
83 | <para> | |
84 | The <computeroutput><classname>domain::as_expr</classname><></computeroutput> and | |
85 | <computeroutput><classname>domain::as_child</classname><></computeroutput> member | |
86 | templates define how non-Proto objects are turned into Proto terminals and how Proto | |
87 | expressions should be processed before they are combined to form larger expressions. | |
88 | They can be overridden in a derived domain for customization. See their descriptions to | |
89 | understand how Proto uses these two templates and what their default behavior is. | |
90 | </para> | |
91 | </description> | |
92 | <typedef name="proto_grammar"> | |
93 | <type>Grammar</type> | |
94 | </typedef> | |
95 | <typedef name="proto_generator"> | |
96 | <type>Generator</type> | |
97 | </typedef> | |
98 | <typedef name="proto_super_domain"> | |
99 | <type>Super</type> | |
100 | </typedef> | |
101 | ||
102 | <struct name="as_expr"> | |
103 | <template> | |
104 | <template-type-parameter name="T"/> | |
105 | </template> | |
106 | <inherit><type><classname>proto::callable</classname></type></inherit> | |
107 | <purpose> | |
108 | A callable unary MonomorphicFunctionObject that specifies how objects are turned into | |
109 | Proto expressions in this domain. The resulting expression object is suitable for storage | |
110 | in a local variable. | |
111 | </purpose> | |
112 | <description> | |
113 | <para> | |
114 | A unary MonomorphicFunctionObject that specifies how objects are turned into Proto | |
115 | expressions in this domain. The resulting expression object is suitable for storage | |
116 | in a local variable. In that scenario, it is usually preferable to return | |
117 | expressions by value; and, in the case of objects that are not yet Proto expressions, | |
118 | to wrap them by value (if possible) in a new Proto terminal expression. (Contrast | |
119 | this description with the description for | |
120 | <computeroutput><classname>proto::domain::as_child</classname></computeroutput>.) | |
121 | </para> | |
122 | <para> | |
123 | The <computeroutput>as_expr</computeroutput> function object turns objects into | |
124 | Proto expressions, if they are not already, by making them Proto terminals held by | |
125 | value if possible. Objects that are already Proto expressions are simply returned | |
126 | by value. If | |
127 | <computeroutput>wants_basic_expr<Generator>::value</computeroutput> is true, | |
128 | then let <emphasis>E</emphasis> be | |
129 | <computeroutput><classname>proto::basic_expr</classname></computeroutput>; | |
130 | otherwise, let <emphasis>E</emphasis> be | |
131 | <computeroutput><classname>proto::expr</classname></computeroutput>. | |
132 | Given an lvalue <computeroutput>t</computeroutput> of type | |
133 | <computeroutput>T</computeroutput>: | |
134 | <itemizedlist> | |
135 | <listitem> | |
136 | If <computeroutput>T</computeroutput> is not a Proto expression type, the resulting | |
137 | terminal is calculated as follows: | |
138 | <itemizedlist> | |
139 | <listitem> | |
140 | If <computeroutput>T</computeroutput> is a function type, an abstract type, or | |
141 | a type derived from <computeroutput>std::ios_base</computeroutput>, let | |
142 | <replaceable>A</replaceable> be <computeroutput>T &</computeroutput>. | |
143 | </listitem> | |
144 | <listitem> | |
145 | Otherwise, let <replaceable>A</replaceable> be the type | |
146 | <computeroutput>T</computeroutput> stripped of cv-qualifiers. | |
147 | </listitem> | |
148 | </itemizedlist> | |
149 | Then, the result of <computeroutput>as_expr<T>()(t)</computeroutput> is | |
150 | <computeroutput>Generator()(<replaceable>E</replaceable><tag::terminal, | |
151 | term< <replaceable>A</replaceable> > >::make(t))</computeroutput>. | |
152 | </listitem> | |
153 | <listitem> | |
154 | Otherwise, the result is <computeroutput>t</computeroutput> converted to an | |
155 | (un-const) rvalue. | |
156 | </listitem> | |
157 | </itemizedlist> | |
158 | </para> | |
159 | </description> | |
160 | <typedef name="result_type"> | |
161 | <type><replaceable>see-below</replaceable></type> | |
162 | </typedef> | |
163 | <method-group name="public member functions"> | |
164 | <method name="operator()" cv="const"> | |
165 | <type>result_type</type> | |
166 | <parameter name="t"> | |
167 | <paramtype>T &</paramtype> | |
168 | <description> | |
169 | <para>The object to wrap.</para> | |
170 | </description> | |
171 | </parameter> | |
172 | </method> | |
173 | </method-group> | |
174 | </struct> | |
175 | ||
176 | <struct name="as_child"> | |
177 | <template> | |
178 | <template-type-parameter name="T"/> | |
179 | </template> | |
180 | <inherit><type><classname>proto::callable</classname></type></inherit> | |
181 | <purpose> | |
182 | A callable unary MonomorphicFunctionObject that specifies how objects are turned into | |
183 | Proto expressions in this domain, for use in scenarios where the resulting expression is | |
184 | intended to be made a child of another expression. | |
185 | </purpose> | |
186 | <description> | |
187 | <para> | |
188 | A unary MonomorphicFunctionObject that specifies how objects are turned into Proto | |
189 | expressions in this domain. The resulting expression object is suitable for storage | |
190 | as a child of another expression. In that scenario, it is usually | |
191 | preferable to store child expressions by reference; or, in the case of objects that | |
192 | are not yet Proto expressions, to wrap them by reference in a new Proto terminal | |
193 | expression. (Contrast this description with the description for | |
194 | <computeroutput><classname>proto::domain::as_expr</classname></computeroutput>.) | |
195 | </para> | |
196 | <para> | |
197 | The <computeroutput>as_child</computeroutput> function object turns objects into | |
198 | Proto expressions, if they are not already, by making them Proto terminals held by | |
199 | reference. Objects that are already Proto expressions are simply returned by | |
200 | reference. If | |
201 | <computeroutput>wants_basic_expr<Generator>::value</computeroutput> is true, | |
202 | then let <emphasis>E</emphasis> be | |
203 | <computeroutput><classname>proto::basic_expr</classname></computeroutput>; | |
204 | otherwise, let <emphasis>E</emphasis> be | |
205 | <computeroutput><classname>proto::expr</classname></computeroutput>. | |
206 | Given an lvalue <computeroutput>t</computeroutput> of type | |
207 | <computeroutput>T</computeroutput>: | |
208 | <itemizedlist> | |
209 | <listitem> | |
210 | If <computeroutput>T</computeroutput> is not a Proto expression type, the resulting | |
211 | terminal is | |
212 | <computeroutput>Generator()(<replaceable>E</replaceable><tag::terminal, | |
213 | term< <computeroutput>T &</computeroutput> > >::make(t))</computeroutput>. | |
214 | </listitem> | |
215 | <listitem> | |
216 | Otherwise, the result is the lvalue <computeroutput>t</computeroutput>. | |
217 | </listitem> | |
218 | </itemizedlist> | |
219 | </para> | |
220 | </description> | |
221 | <typedef name="result_type"> | |
222 | <type><replaceable>see-below</replaceable></type> | |
223 | </typedef> | |
224 | <method-group name="public member functions"> | |
225 | <method name="operator()" cv="const"> | |
226 | <type>result_type</type> | |
227 | <parameter name="t"> | |
228 | <paramtype>T &</paramtype> | |
229 | <description> | |
230 | <para>The object to wrap.</para> | |
231 | </description> | |
232 | </parameter> | |
233 | </method> | |
234 | </method-group> | |
235 | </struct> | |
236 | </struct> | |
237 | ||
238 | <!-- proto::default_domain --> | |
239 | <struct name="default_domain"> | |
240 | <inherit><classname>proto::domain</classname><></inherit> | |
241 | <purpose>The domain expressions have by default, if <computeroutput> | |
242 | <classname alt="proto::extends">proto::extends<></classname></computeroutput> has not been used | |
243 | to associate a domain with an expression.</purpose> | |
244 | </struct> | |
245 | ||
246 | <!-- proto::basic_default_domain --> | |
247 | <struct name="basic_default_domain"> | |
248 | <inherit><classname>proto::domain</classname>< <classname>proto::basic_default_generator</classname> ></inherit> | |
249 | <purpose>A domain similiar in purpose to <classname>proto::default_domain</classname>, except stating | |
250 | a preference for <classname>proto::basic_expr</classname><> over <classname>proto::expr</classname><>.</purpose> | |
251 | </struct> | |
252 | ||
253 | <!-- proto::deduce_domain --> | |
254 | <struct name="deduce_domain"> | |
255 | <purpose>A pseudo-domain for use in functions and metafunctions that require a domain parameter. | |
256 | It indicates that the domain of the parent node should be inferred from the domains of the child nodes.</purpose> | |
257 | <description> | |
258 | <para> | |
259 | When <computeroutput>proto::deduce_domain</computeroutput> is used as a domain — either | |
260 | explicitly or implicitly by | |
261 | <computeroutput><functionname>proto::make_expr</functionname>()</computeroutput>, | |
262 | <computeroutput><functionname>proto::unpack_expr</functionname>()</computeroutput>, | |
263 | or Proto's operator overloads — Proto will use the domains of the child expressions to | |
264 | compute the domain of the parent. It is done in such a way that (A) expressions in domains | |
265 | that share a common super-domain are interoperable, and (B) expressions that are in | |
266 | the default domain (or a sub-domain thereof) are interoperable with <emphasis>all</emphasis> | |
267 | expressions. The rules are as follows: | |
268 | <itemizedlist> | |
269 | <listitem> | |
270 | A sub-domain is <emphasis>stronger</emphasis> than its super-domain. | |
271 | </listitem> | |
272 | <listitem> | |
273 | <computeroutput><classname>proto::default_domain</classname></computeroutput>, | |
274 | <computeroutput><classname>proto::basic_default_domain</classname></computeroutput> | |
275 | and all their sub-domains are <emphasis>weaker</emphasis> than all other domains. | |
276 | </listitem> | |
277 | <listitem> | |
278 | <computeroutput><classname>proto::basic_default_domain</classname></computeroutput> | |
279 | is weaker than | |
280 | <computeroutput><classname>proto::default_domain</classname></computeroutput>. | |
281 | </listitem> | |
282 | <listitem> | |
283 | For each child, define a set of domains <emphasis>S<subscript>N</subscript></emphasis> | |
284 | that includes the child's domain and all its super-domains. | |
285 | </listitem> | |
286 | <listitem> | |
287 | Define a set <emphasis>I<subscript>S</subscript></emphasis> that is the intersection of | |
288 | all the individual sets <emphasis>S<subscript>N</subscript></emphasis> that don't contain | |
289 | <computeroutput><classname>proto::default_domain</classname></computeroutput> or | |
290 | <computeroutput><classname>proto::basic_default_domain</classname></computeroutput>. | |
291 | </listitem> | |
292 | <listitem> | |
293 | Define a set <emphasis>I<subscript>W</subscript></emphasis> that is the intersection of | |
294 | all the individual sets <emphasis>S<subscript>N</subscript></emphasis> that contain | |
295 | <computeroutput><classname>proto::default_domain</classname></computeroutput> or | |
296 | <computeroutput><classname>proto::basic_default_domain</classname></computeroutput>. | |
297 | </listitem> | |
298 | <listitem> | |
299 | Define a set <emphasis>P</emphasis> that is the union of | |
300 | <emphasis>I<subscript>S</subscript></emphasis> and | |
301 | <emphasis>I<subscript>W</subscript></emphasis>. | |
302 | </listitem> | |
303 | <listitem> | |
304 | The common domain is the strongest domain in set <emphasis>P</emphasis>, with the | |
305 | following caveats. | |
306 | </listitem> | |
307 | <listitem> | |
308 | Let <emphasis>U</emphasis> be the union of all sets | |
309 | <emphasis>S<subscript>N</subscript></emphasis>. If the result is | |
310 | <computeroutput><classname>proto::default_domain</classname></computeroutput> or | |
311 | <computeroutput><classname>proto::basic_default_domain</classname></computeroutput> | |
312 | and <emphasis>U</emphasis> contains an element that is <emphasis>not </emphasis> | |
313 | <computeroutput><classname>proto::default_domain</classname></computeroutput> or | |
314 | <computeroutput><classname>proto::basic_default_domain</classname></computeroutput>, | |
315 | it is an error. | |
316 | </listitem> | |
317 | </itemizedlist> | |
318 | </para> | |
319 | <para> | |
320 | Note: the above description sounds like it would be expensive to compute at compile time. | |
321 | In fact, it can all be done using C++ function overloading. | |
322 | </para> | |
323 | </description> | |
324 | </struct> | |
325 | ||
326 | <!-- proto::is_domain --> | |
327 | <struct name="is_domain"> | |
328 | <template> | |
329 | <template-type-parameter name="T"/> | |
330 | </template> | |
331 | <inherit> | |
332 | <type>mpl::bool_< <replaceable>true-or-false</replaceable> ></type> | |
333 | </inherit> | |
334 | <description> | |
335 | <para> | |
336 | A metafunction that returns <computeroutput>mpl::true_</computeroutput> if the type | |
337 | <computeroutput>T</computeroutput> is the type of a Proto domain; | |
338 | <computeroutput>mpl::false_</computeroutput> otherwise. If <computeroutput>T</computeroutput> | |
339 | inherits from <computeroutput><classname alt="proto::domain">proto::domain<></classname></computeroutput>, | |
340 | <computeroutput>is_domain<T></computeroutput> is <computeroutput>mpl::true_</computeroutput>. | |
341 | </para> | |
342 | </description> | |
343 | </struct> | |
344 | ||
345 | <!-- proto::domain_of --> | |
346 | <struct name="domain_of"> | |
347 | <template> | |
348 | <template-type-parameter name="T"/> | |
349 | </template> | |
350 | <description> | |
351 | <para> | |
352 | A metafunction that returns the domain of a given type. If <computeroutput>T</computeroutput> is a Proto | |
353 | expression type, it returns that expression's associated domain. If not, it returns | |
354 | <computeroutput><classname>proto::default_domain</classname></computeroutput>. | |
355 | </para> | |
356 | </description> | |
357 | <typedef name="type"> | |
358 | <type><replaceable>domain-of-T</replaceable></type> | |
359 | </typedef> | |
360 | </struct> | |
361 | ||
362 | <!-- proto::base_expr --><!-- | |
363 | <struct name="base_expr"> | |
364 | <template> | |
365 | <template-type-parameter name="Domain"/> | |
366 | <template-type-parameter name="Tag"/> | |
367 | <template-type-parameter name="Args"/> | |
368 | </template> | |
369 | <description> | |
370 | <para> | |
371 | Given a domain, a tag type and an argument list, | |
372 | compute the type of the expression to generate. This is | |
373 | either an instance of | |
374 | <computeroutput><classname>proto::basic_expr</classname><></computeroutput> or | |
375 | <computeroutput><classname>proto::expr</classname><></computeroutput>. | |
376 | </para> | |
377 | </description> | |
378 | <typedef name="A"> | |
379 | <purpose>For exposition only</purpose> | |
380 | <type><classname>proto::basic_expr</classname>< Tag, Args ></type> | |
381 | </typedef> | |
382 | <typedef name="B"> | |
383 | <purpose>For exposition only</purpose> | |
384 | <type><classname>proto::expr</classname>< Tag, Args ></type> | |
385 | </typedef> | |
386 | <typedef name="type"> | |
387 | <type>typename mpl::if_<<classname>proto::wants_basic_expr</classname>< Domain >, A, B>::type</type> | |
388 | </typedef> | |
389 | </struct>--> | |
390 | ||
391 | </namespace> | |
392 | </namespace> | |
393 | </header> |