• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/extends.hpp">
10  <para>Macros and a base class for defining end-user expression types </para>
11  <namespace name="boost">
12    <namespace name="proto">
13
14      <!-- proto::is_proto_expr -->
15      <struct name="is_proto_expr">
16        <purpose>Empty type to be used as a dummy template parameter of POD expression wrappers. It allows
17          argument-dependent lookup to find Proto's operator overloads.</purpose>
18        <description>
19          <para>
20            <computeroutput>proto::is_proto_expr</computeroutput> allows argument-dependent lookup to find Proto's operator overloads. For example:
21          </para>
22          <para>
23            <programlisting> template&lt;typename T, typename Dummy = <classname>proto::is_proto_expr</classname>&gt;
24 struct my_terminal
25 {
26     <macroname>BOOST_PROTO_BASIC_EXTENDS</macroname>(
27         typename <classname>proto::terminal</classname>&lt;T&gt;::type
28       , my_terminal&lt;T&gt;
29       , <classname>proto::default_domain</classname>
30     )
31 };
32
33 // ...
34 my_terminal&lt;int&gt; _1, _2;
35 _1 + _2; // OK, uses proto::operator+</programlisting>
36          </para>
37          <para>
38            Without the second <computeroutput>Dummy</computeroutput> template parameter, Proto's operator overloads
39            would not be considered by name lookup.
40          </para>
41        </description>
42      </struct>
43
44      <!-- proto::extends -->
45      <struct name="extends">
46        <template>
47          <template-type-parameter name="Expr"/>
48          <template-type-parameter name="Derived"/>
49          <template-type-parameter name="Domain">
50            <default><classname>proto::default_domain</classname></default>
51          </template-type-parameter>
52        </template>
53        <purpose>For adding behaviors to a Proto expression template.</purpose>
54        <description>
55          <para>
56            Use <computeroutput>proto::extends&lt;&gt;</computeroutput> to give expressions in your
57            domain custom data members and member functions.
58          </para>
59          <para>
60            Conceptually, using <computeroutput>proto::extends&lt;&gt;</computeroutput> is akin
61            to inheriting from <computeroutput><classname>proto::expr</classname>&lt;&gt;</computeroutput>
62            and adding your own members. Using <computeroutput>proto::extends&lt;&gt;</computeroutput> is
63            generally preferrable to straight inheritance because the members that would be inherited from
64            <computeroutput><classname>proto::expr</classname>&lt;&gt;</computeroutput> would
65            be wrong; they would incorrectly slice off your additional members when building
66            larger expressions from smaller ones. <computeroutput>proto::extends&lt;&gt;</computeroutput>
67            automatically gives your expression types the appropriate operator overloads that
68            preserve your domain-specific members when composing expression trees.
69          </para>
70          <para>
71            Expression extensions are typically defined as follows:
72          </para>
73          <para>
74            <programlisting>template&lt; typename Expr &gt;
75struct my_expr
76  : proto::extends&lt;
77        Expr            // The expression type we're extending
78      , my_expr&lt; Expr &gt; // The type we're defining
79      , my_domain       // The domain associated with this expression extension
80    &gt;
81{
82    // An expression extension is constructed from the expression
83    // it is extending.
84    my_expr( Expr const &amp; e = Expr() )
85      : my_expr::proto_extends( e )
86    {}
87
88    // Unhide proto::extends::operator=
89    // (This is only necessary if a lazy assignment operator
90    // makes sense for your domain-specific language.)
91    BOOST_PROTO_EXTENDS_USING_ASSIGN(my_expr)
92
93    /*
94    ... domain-specific members go here ...
95    */
96};</programlisting>
97          </para>
98          <para>
99            See also:
100            <itemizedlist>
101              <listitem>
102                <computeroutput><macroname>BOOST_PROTO_EXTENDS</macroname>()</computeroutput>
103              </listitem>
104              <listitem>
105                <computeroutput><macroname>BOOST_PROTO_EXTENDS_USING_ASSIGN</macroname>()</computeroutput>
106              </listitem>
107              <listitem>
108                <computeroutput><macroname>BOOST_PROTO_EXTENDS_USING_ASSIGN_NON_DEPENDENT</macroname>()</computeroutput>
109              </listitem>
110            </itemizedlist>
111          </para>
112        </description>
113        <struct name="result">
114          <template>
115            <template-type-parameter name="Signature"/>
116          </template>
117          <typedef name="type">
118            <type><replaceable>unspecified</replaceable></type>
119          </typedef>
120          <description>
121            <para>So that <computeroutput>boost::result_of&lt;&gt;</computeroutput>
122            can compute the return type of <computeroutput>proto::extends::operator()</computeroutput>.
123          </para>
124          </description>
125        </struct>
126        <typedef name="proto_base_expr">
127          <type>typename Expr::proto_base_expr</type>
128        </typedef>
129        <typedef name="proto_domain">
130          <type>Domain</type>
131        </typedef>
132        <typedef name="proto_derived_expr">
133          <type>Derived</type>
134        </typedef>
135        <typedef name="proto_extends">
136          <type>extends</type>
137        </typedef>
138        <typedef name="proto_tag">
139          <type>typename proto_base_expr::proto_tag</type>
140        </typedef>
141        <typedef name="proto_args">
142          <type>typename proto_base_expr::proto_args</type>
143        </typedef>
144        <typedef name="proto_arity">
145          <type>typename proto_base_expr::proto_arity</type>
146        </typedef>
147        <typedef name="proto_grammar">
148          <type>typename proto_base_expr::proto_grammar</type>
149        </typedef>
150        <typedef name="proto_childN">
151          <purpose>For each <replaceable>N</replaceable> in <replaceable>[0,max(1,proto_arity_c))</replaceable></purpose>
152          <type>typename proto_base_expr::proto_child<replaceable>N</replaceable></type>
153        </typedef>
154
155        <!-- constructors -->
156        <constructor/>
157        <constructor>
158          <parameter name="that">
159            <paramtype><classname>extends</classname> const &amp;</paramtype>
160          </parameter>
161        </constructor>
162        <constructor>
163          <parameter name="expr_">
164            <paramtype>Expr const &amp;</paramtype>
165          </parameter>
166        </constructor>
167
168        <method-group name="public static functions">
169          <method name="make" specifiers="static">
170            <type>Derived const</type>
171            <parameter name="expr">
172              <paramtype>Expr const &amp;</paramtype>
173            </parameter>
174            <description>
175              <para>Construct an expression extension from the base expression.</para>
176            </description>
177            <return>Derived(expr)</return>
178          </method>
179        </method-group>
180
181        <method-group name="public member functions">
182
183          <!-- proto_base() -->
184          <method name="proto_base">
185            <type>proto_base_expr &amp;</type>
186            <returns><computeroutput>proto_expr_.proto_base()</computeroutput></returns>
187            <throws><simpara>Will not throw.</simpara></throws>
188          </method>
189          <method name="proto_base" cv="const">
190            <type>proto_base_expr const &amp;</type>
191            <returns><computeroutput>proto_expr_.proto_base()</computeroutput></returns>
192            <throws><simpara>Will not throw.</simpara></throws>
193          </method>
194
195          <!-- operator= -->
196          <method name="operator=">
197            <type><replaceable>unspecified</replaceable></type>
198            <template>
199              <template-type-parameter name="A"/>
200            </template>
201            <parameter name="a">
202              <paramtype>A &amp;</paramtype>
203            </parameter>
204            <description>
205              <para>Lazy assignment expression</para>
206            </description>
207            <returns>
208              <para>A new expression node representing the assignment operation.</para>
209            </returns>
210          </method>
211
212          <method name="operator=">
213            <type><replaceable>unspecified</replaceable></type>
214            <template>
215              <template-type-parameter name="A"/>
216            </template>
217            <parameter name="a">
218              <paramtype>A const &amp;</paramtype>
219            </parameter>
220            <description>
221              <para>
222                This is an overloaded member function, provided for convenience. It differs from
223                the above function only in what argument(s) it accepts.
224              </para>
225            </description>
226          </method>
227
228          <method name="operator=" cv="const">
229            <type><replaceable>unspecified</replaceable></type>
230            <template>
231              <template-type-parameter name="A"/>
232            </template>
233            <parameter name="a">
234              <paramtype>A &amp;</paramtype>
235            </parameter>
236            <description>
237              <para>
238                This is an overloaded member function, provided for convenience. It differs from
239                the above function only in what argument(s) it accepts.
240              </para>
241            </description>
242          </method>
243
244          <method name="operator=" cv="const">
245            <type><replaceable>unspecified</replaceable></type>
246            <template>
247              <template-type-parameter name="A"/>
248            </template>
249            <parameter name="a">
250              <paramtype>A const &amp;</paramtype>
251            </parameter>
252            <description>
253              <para>
254                This is an overloaded member function, provided for convenience. It differs from
255                the above function only in what argument(s) it accepts.
256              </para>
257            </description>
258          </method>
259
260          <!-- operator[] -->
261          <method name="operator[]">
262            <type><replaceable>unspecified</replaceable></type>
263            <template>
264              <template-type-parameter name="A"/>
265            </template>
266            <parameter name="a">
267              <paramtype>A &amp;</paramtype>
268            </parameter>
269            <description>
270              <para>Lazy subscript expression</para>
271            </description>
272            <returns>
273              <para>A new expression node representing the subscript operation.</para>
274            </returns>
275          </method>
276
277          <method name="operator[]">
278            <type><replaceable>unspecified</replaceable></type>
279            <template>
280              <template-type-parameter name="A"/>
281            </template>
282            <parameter name="a">
283              <paramtype>A const &amp;</paramtype>
284            </parameter>
285            <description>
286              <para>
287                This is an overloaded member function, provided for convenience. It differs from
288                the above function only in what argument(s) it accepts.
289              </para>
290            </description>
291          </method>
292
293          <method name="operator[]" cv="const">
294            <type><replaceable>unspecified</replaceable></type>
295            <template>
296              <template-type-parameter name="A"/>
297            </template>
298            <parameter name="a">
299              <paramtype>A &amp;</paramtype>
300            </parameter>
301            <description>
302              <para>
303                This is an overloaded member function, provided for convenience. It differs from
304                the above function only in what argument(s) it accepts.
305              </para>
306            </description>
307          </method>
308
309          <method name="operator[]" cv="const">
310            <type><replaceable>unspecified</replaceable></type>
311            <template>
312              <template-type-parameter name="A"/>
313            </template>
314            <parameter name="a">
315              <paramtype>A const &amp;</paramtype>
316            </parameter>
317            <description>
318              <para>
319                This is an overloaded member function, provided for convenience. It differs from
320                the above function only in what argument(s) it accepts.
321              </para>
322            </description>
323          </method>
324
325          <!-- operator() -->
326          <method name="operator()">
327            <type><replaceable>unspecified</replaceable></type>
328            <template>
329              <template-type-parameter name="A" pack="1"/>
330            </template>
331            <parameter name="a" pack="1">
332              <paramtype>A const &amp;</paramtype>
333            </parameter>
334            <description>
335              <para>Lazy function call</para>
336            </description>
337            <returns>
338              <para>A new expression node representing the function call operation.</para>
339            </returns>
340          </method>
341
342          <method name="operator()" cv="const">
343            <type><replaceable>unspecified</replaceable></type>
344            <template>
345              <template-type-parameter name="A" pack="1"/>
346            </template>
347            <parameter name="a" pack="1">
348              <paramtype>A const &amp;</paramtype>
349            </parameter>
350            <description>
351              <para>
352                This is an overloaded member function, provided for convenience. It differs from
353                the above function only in what argument(s) it accepts.
354              </para>
355            </description>
356          </method>
357        </method-group>
358
359        <data-member name="proto_expr_">
360          <type>Expr</type>
361          <purpose>For exposition only.</purpose>
362        </data-member>
363
364        <data-member name="proto_arity_c" specifiers="static">
365          <type>const long</type>
366          <purpose><computeroutput>= proto_base_expr::proto_arity_c;</computeroutput></purpose>
367        </data-member>
368
369      </struct>
370
371    </namespace>
372  </namespace>
373
374  <macro name="BOOST_PROTO_EXTENDS" kind="functionlike">
375    <macro-parameter name="Expr"/>
376    <macro-parameter name="Derived"/>
377    <macro-parameter name="Domain"/>
378    <purpose>For creating expression wrappers that add behaviors to a Proto expression template, like
379      <computeroutput><classname alt="boost::proto::extends">proto::extends&lt;&gt;</classname></computeroutput>,
380      but while retaining POD-ness of the expression wrapper.</purpose>
381    <description>
382      <para>
383        Equivalent to:
384        <programlisting><macroname>BOOST_PROTO_BASIC_EXTENDS</macroname>(Expr, Derived, Domain)
385<macroname>BOOST_PROTO_EXTENDS_ASSIGN</macroname>()
386<macroname>BOOST_PROTO_EXTENDS_SUBSCRIPT</macroname>()
387<macroname>BOOST_PROTO_EXTENDS_FUNCTION</macroname>()</programlisting>
388      </para>
389      <para>If the <computeroutput>Domain</computeroutput> parameter is dependent, you can specify it as
390        <computeroutput>typename Domain</computeroutput>, as in
391        <computeroutput>BOOST_PROTO_EXTENDS(Expr, Derived, typename Domain)</computeroutput>
392      </para>
393      <para>
394        <emphasis role="bold">Example:</emphasis><programlisting>template&lt; class Expr &gt;
395struct my_expr;
396
397struct my_domain
398  : <classname alt="boost::proto::domain">proto::domain</classname>&lt; <classname alt="boost::proto::pod_generator">proto::pod_generator</classname>&lt; my_expr &gt; &gt;
399{};
400
401template&lt; class Expr &gt;
402struct my_expr
403{
404    // OK, this makes my_expr&lt;&gt; a valid Proto expression extension.
405    // my_expr&lt;&gt; has overloaded assignment, subscript,
406    // and function call operators that build expression templates.
407    <macroname>BOOST_PROTO_EXTENDS</macroname>(Expr, my_expr, my_domain)
408};
409
410// OK, my_expr&lt;&gt; is POD, so this is statically initialized:
411my_expr&lt; <classname alt="boost::proto::terminal">proto::terminal</classname>&lt;int&gt;::type &gt; const _1 = {{1}};</programlisting>
412      </para>
413    </description>
414  </macro>
415
416  <macro name="BOOST_PROTO_BASIC_EXTENDS" kind="functionlike">
417    <macro-parameter name="Expr"/>
418    <macro-parameter name="Derived"/>
419    <macro-parameter name="Domain"/>
420    <purpose>For creating expression wrappers that add members to a Proto expression template, like
421      <computeroutput><classname alt="boost::proto::extends">proto::extends&lt;&gt;</classname></computeroutput>,
422      but while retaining POD-ness of the expression wrapper.</purpose>
423    <description>
424      <para>
425        <computeroutput>BOOST_PROTO_BASIC_EXTENDS()</computeroutput> adds the basic typedefs, member functions, and
426        data members necessary to make a struct a valid Proto expression extension. It does <emphasis>not</emphasis>
427        add any constructors, virtual functions or access control blocks that would render the containing
428        struct non-POD.
429      </para>
430      <para>
431        <computeroutput>Expr</computeroutput> is the Proto expression that the enclosing struct extends.
432        <computeroutput>Derived</computeroutput> is the type of the enclosing struct.
433        <computeroutput>Domain</computeroutput> is the Proto domain to which this expression extension belongs.
434        (See <computeroutput><classname alt="boost::proto::domain">proto::domain&lt;&gt;</classname></computeroutput>.)
435        Can be preceeded with "<computeroutput>typename</computeroutput>" if the specified domain is a dependent type.
436      </para>
437      <para><computeroutput>BOOST_PROTO_BASIC_EXTENDS()</computeroutput> adds to its enclosing struct
438        exactly one data member of type <computeroutput>Expr</computeroutput>.
439      </para>
440      <para>If the <computeroutput>Domain</computeroutput> parameter is dependent, you can specify it as
441        <computeroutput>typename Domain</computeroutput>, as in
442        <computeroutput>BOOST_PROTO_BASIC_EXTENDS(Expr, Derived, typename Domain)</computeroutput>
443      </para>
444      <para>
445        <emphasis role="bold">Example:</emphasis><programlisting>template&lt; class Expr &gt;
446struct my_expr;
447
448struct my_domain
449  : <classname alt="boost::proto::domain">proto::domain</classname>&lt; <classname alt="boost::proto::pod_generator">proto::pod_generator</classname>&lt; my_expr &gt; &gt;
450{};
451
452template&lt; class Expr &gt;
453struct my_expr
454{
455    // OK, this makes my_expr&lt;&gt; a valid Proto expression extension.
456    // my_expr&lt;&gt; does /not/ have overloaded assignment, subscript,
457    // and function call operators that build expression templates, however.
458    <macroname>BOOST_PROTO_BASIC_EXTENDS</macroname>(Expr, my_expr, my_domain)
459};
460
461// OK, my_expr&lt;&gt; is POD, so this is statically initialized:
462my_expr&lt; <classname alt="boost::proto::terminal">proto::terminal</classname>&lt;int&gt;::type &gt; const _1 = {{1}};</programlisting>
463      </para>
464      <para>
465        See also:
466        <itemizedlist>
467          <listitem>
468            <computeroutput><macroname>BOOST_PROTO_EXTENDS_ASSIGN</macroname>()</computeroutput>
469          </listitem>
470          <listitem>
471            <computeroutput><macroname>BOOST_PROTO_EXTENDS_SUBSCRIPT</macroname>()</computeroutput>
472          </listitem>
473          <listitem>
474            <computeroutput><macroname>BOOST_PROTO_EXTENDS_FUNCTION</macroname>()</computeroutput>
475          </listitem>
476          <listitem>
477            <computeroutput><macroname>BOOST_PROTO_EXTENDS</macroname>()</computeroutput>
478          </listitem>
479        </itemizedlist>
480      </para>
481    </description>
482  </macro>
483
484  <macro name="BOOST_PROTO_EXTENDS_ASSIGN" kind="functionlike">
485    <purpose>For adding to an expression extension class an overloaded assignment operator that
486      builds an expression template.</purpose>
487    <description>
488      <para>
489        Use <computeroutput>BOOST_PROTO_EXTENDS_ASSIGN()</computeroutput> after <computeroutput>
490        <macroname>BOOST_PROTO_BASIC_EXTENDS</macroname>()</computeroutput> to give an expression
491        extension class an overloaded assignment operator that builds an expression template.
492      </para>
493      <para>
494        See also:
495        <itemizedlist>
496          <listitem>
497            <computeroutput><macroname>BOOST_PROTO_BASIC_EXTENDS</macroname>()</computeroutput>
498          </listitem>
499          <listitem>
500            <computeroutput><macroname>BOOST_PROTO_EXTENDS_SUBSCRIPT</macroname>()</computeroutput>
501          </listitem>
502          <listitem>
503            <computeroutput><macroname>BOOST_PROTO_EXTENDS_FUNCTION</macroname>()</computeroutput>
504          </listitem>
505          <listitem>
506            <computeroutput><macroname>BOOST_PROTO_EXTENDS</macroname>()</computeroutput>
507          </listitem>
508        </itemizedlist>
509      </para>
510    </description>
511  </macro>
512
513  <macro name="BOOST_PROTO_EXTENDS_FUNCTION" kind="functionlike">
514    <purpose>For adding to an expression extension class a set of overloaded function call operators
515      that build expression templates.</purpose>
516    <description>
517      <para>
518        Use <computeroutput>BOOST_PROTO_EXTENDS_FUNCTION()</computeroutput> after <computeroutput>
519        <macroname>BOOST_PROTO_BASIC_EXTENDS</macroname>()</computeroutput> to give an expression
520        extension class a set of overloaded function call operators that build expression templates.
521        In addition, <computeroutput>BOOST_PROTO_EXTENDS_FUNCTION()</computeroutput> adds a nested
522        <computeroutput>result&lt;&gt;</computeroutput> class template that is a metafunction for
523        calculating the return type of the overloaded function call operators.
524      </para>
525      <para>
526        See also:
527        <itemizedlist>
528          <listitem>
529            <computeroutput><macroname>BOOST_PROTO_BASIC_EXTENDS</macroname>()</computeroutput>
530          </listitem>
531          <listitem>
532            <computeroutput><macroname>BOOST_PROTO_EXTENDS_ASSIGN</macroname>()</computeroutput>
533          </listitem>
534          <listitem>
535            <computeroutput><macroname>BOOST_PROTO_EXTENDS_SUBSCRIPT</macroname>()</computeroutput>
536          </listitem>
537          <listitem>
538            <computeroutput><macroname>BOOST_PROTO_EXTENDS</macroname>()</computeroutput>
539          </listitem>
540        </itemizedlist>
541      </para>
542    </description>
543  </macro>
544
545  <macro name="BOOST_PROTO_EXTENDS_SUBSCRIPT" kind="functionlike">
546    <purpose>For adding to an expression extension class an overloaded subscript operator that
547      builds an expression template.</purpose>
548    <description>
549      <para>
550        Use <computeroutput>BOOST_PROTO_EXTENDS_SUBSCRIPT()</computeroutput> after <computeroutput>
551        <macroname>BOOST_PROTO_BASIC_EXTENDS</macroname>()</computeroutput> to give an expression
552        extension class an overloaded subscript operator that builds an expression template.
553      </para>
554      <para>
555        See also:
556        <itemizedlist>
557          <listitem>
558            <computeroutput><macroname>BOOST_PROTO_BASIC_EXTENDS</macroname>()</computeroutput>
559          </listitem>
560          <listitem>
561            <computeroutput><macroname>BOOST_PROTO_EXTENDS_ASSIGN</macroname>()</computeroutput>
562          </listitem>
563          <listitem>
564            <computeroutput><macroname>BOOST_PROTO_EXTENDS_FUNCTION</macroname>()</computeroutput>
565          </listitem>
566          <listitem>
567            <computeroutput><macroname>BOOST_PROTO_EXTENDS</macroname>()</computeroutput>
568          </listitem>
569        </itemizedlist>
570      </para>
571    </description>
572  </macro>
573
574  <macro name="BOOST_PROTO_EXTENDS_USING_ASSIGN" kind="functionlike">
575    <macro-parameter name="Derived"/>
576    <purpose>For exposing in classes that inherit from
577      <computeroutput><classname alt="boost::proto::extends">proto::extends&lt;&gt;</classname></computeroutput>
578      the overloaded assignment operators defined therein.</purpose>
579    <description>
580      <para>
581        The standard usage of
582        <computeroutput><classname alt="boost::proto::extends">proto::extends&lt;&gt;</classname></computeroutput>
583        is to inherit from it. However, the derived class automatically gets a compiler-generated assignment
584        operator that will hide the ones defined in
585        <computeroutput><classname alt="boost::proto::extends">proto::extends&lt;&gt;</classname></computeroutput>.
586        Use <code>BOOST_PROTO_EXTENDS_USING_ASSIGN()</code> in the derived class to unhide the assignment
587        operators defined in
588        <computeroutput><classname alt="boost::proto::extends">proto::extends&lt;&gt;</classname></computeroutput>.
589      </para>
590      <para>
591        See <computeroutput><classname alt="boost::proto::extends">proto::extends&lt;&gt;</classname></computeroutput>
592        for an example that demonstrates usage of <code>BOOST_PROTO_EXTENDS_USING_ASSIGN()</code>.
593      </para>
594    </description>
595  </macro>
596
597  <macro name="BOOST_PROTO_EXTENDS_USING_ASSIGN_NON_DEPENDENT" kind="functionlike">
598    <macro-parameter name="Derived"/>
599    <purpose>For exposing in classes that inherit from
600      <computeroutput><classname alt="boost::proto::extends">proto::extends&lt;&gt;</classname></computeroutput>
601      the overloaded assignment operators defined therein. Unlike the
602      <computeroutput><macroname>BOOST_PROTO_EXTENDS_USING_ASSIGN</macroname>()</computeroutput> macro,
603      <code>BOOST_PROTO_EXTENDS_USING_ASSIGN_NON_DEPENDENT()</code> is for use in non-dependent
604      contexts.
605      </purpose>
606    <description>
607      <para>
608        The standard usage of
609        <computeroutput><classname alt="boost::proto::extends">proto::extends&lt;&gt;</classname></computeroutput>
610        is to define a class template that inherits from it. The derived class template automatically gets a
611        compiler-generated assignment operator that hides the ones defined in
612        <computeroutput><classname alt="boost::proto::extends">proto::extends&lt;&gt;</classname></computeroutput>.
613        Using <code>BOOST_PROTO_EXTENDS_USING_ASSIGN()</code> in the derived class solves this problem.
614      </para>
615      <para>
616        However, if the expression extension is an ordinary class and not a class template, the usage of
617        <code>BOOST_PROTO_EXTENDS_USING_ASSIGN()</code> is in a so-called non-dependent context. In plain English,
618        it means it is illegal to use <code>typename</code> in some places where it is required in a class template.
619        In those cases, you should use <code>BOOST_PROTO_EXTENDS_USING_ASSIGN_NON_DEPENDENT()</code> instead.
620      </para>
621      <para>
622		See also:
623		<itemizedlist>
624		  <listitem>
625			<computeroutput><classname alt="boost::proto::extends">proto::extends&lt;&gt;</classname></computeroutput>
626		  </listitem>
627		  <listitem>
628			<computeroutput><macroname>BOOST_PROTO_EXTENDS_USING_ASSIGN</macroname>()</computeroutput>
629		  </listitem>
630		</itemizedlist>
631      </para>
632    </description>
633  </macro>
634
635</header>
636