123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393 |
- <?xml version="1.0" encoding="utf-8"?>
- <!--
- Copyright 2012 Eric Niebler
- Distributed under the Boost
- Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- -->
- <header name="boost/proto/domain.hpp">
- <para>
- Contains definition of the <computeroutput><classname alt="boost::proto::domain">proto::domain<></classname>
- </computeroutput> class template and helpers for defining domains with a generator for customizing expression
- construction and a grammar for controlling operator overloading.
- </para>
- <namespace name="boost">
- <namespace name="proto">
- <!-- proto::domain<> -->
- <struct name="domain">
- <template>
- <template-type-parameter name="Generator">
- <default><classname>proto::default_generator</classname></default>
- </template-type-parameter>
- <template-type-parameter name="Grammar">
- <default><classname>proto::_</classname></default>
- </template-type-parameter>
- <template-type-parameter name="Super">
- <default><replaceable>unspecified</replaceable></default>
- </template-type-parameter>
- </template>
- <inherit><type>Generator</type></inherit>
- <purpose>For use in defining domain tags to be used with <computeroutput>
- <classname alt="proto::extends">proto::extends<></classname></computeroutput>,
- <computeroutput><macroname>BOOST_PROTO_EXTENDS</macroname>()</computeroutput> and
- <computeroutput><macroname>BOOST_PROTO_DEFINE_OPERATORS</macroname>()</computeroutput>.
- A <emphasis>domain</emphasis> associates an expression type with a <emphasis>generator</emphasis>,
- and optionally a <emphasis>grammar</emphasis>. It may also have a super-domain. Expressions
- in a sub-domain are interoperable (i.e. can be combined freely with) expressions in a
- super-domain. Finally, domains control how non-Proto objects are turned into Proto
- expressions and how they are combined to form larger Proto expressions.
- </purpose>
- <description>
- <para>
- The Generator parameter determines how new expressions in the domain are post-processed. Typically, a generator
- wraps all new expressions in a wrapper that imparts domain-specific behaviors to expressions within
- its domain. (See <computeroutput><classname alt="proto::extends">proto::extends<></classname></computeroutput>.)
- </para>
- <para>
- The Grammar parameter determines whether a given expression is valid within the domain, and automatically
- disables any operator overloads which would cause an invalid expression to be created. By default,
- the Grammar parameter defaults to the wildcard, <computeroutput><classname>proto::_</classname>
- </computeroutput>, which makes all expressions valid within the domain.
- </para>
- <para>
- The Super parameter declares the domain currently being defined to be a sub-domain of Super. An expression in
- a sub-domain can be freely combined with expressions in its super-domain (and <emphasis>its</emphasis>
- super-domain, etc.).
- </para>
- <para>
- Example: <programlisting> template<typename Expr>
- struct MyExpr;
- struct MyGrammar
- : <classname>proto::or_</classname>< <classname>proto::terminal</classname><_>, <classname>proto::plus</classname><MyGrammar, MyGrammar> >
- {};
- // Define MyDomain, in which all expressions are
- // wrapped in MyExpr<> and only expressions that
- // conform to MyGrammar are allowed.
- struct MyDomain
- : <classname>proto::domain</classname><<classname>proto::generator</classname><MyExpr>, MyGrammar>
- {};
- // Use MyDomain to define MyExpr
- template<typename Expr>
- struct MyExpr
- : <classname>proto::extends</classname><Expr, MyExpr<Expr>, MyDomain>
- {
- // ...
- };
- </programlisting>
- </para>
- <para>
- The <computeroutput><classname>domain::as_expr</classname><></computeroutput> and
- <computeroutput><classname>domain::as_child</classname><></computeroutput> member
- templates define how non-Proto objects are turned into Proto terminals and how Proto
- expressions should be processed before they are combined to form larger expressions.
- They can be overridden in a derived domain for customization. See their descriptions to
- understand how Proto uses these two templates and what their default behavior is.
- </para>
- </description>
- <typedef name="proto_grammar">
- <type>Grammar</type>
- </typedef>
- <typedef name="proto_generator">
- <type>Generator</type>
- </typedef>
- <typedef name="proto_super_domain">
- <type>Super</type>
- </typedef>
- <struct name="as_expr">
- <template>
- <template-type-parameter name="T"/>
- </template>
- <inherit><type><classname>proto::callable</classname></type></inherit>
- <purpose>
- A callable unary MonomorphicFunctionObject that specifies how objects are turned into
- Proto expressions in this domain. The resulting expression object is suitable for storage
- in a local variable.
- </purpose>
- <description>
- <para>
- A unary MonomorphicFunctionObject that specifies how objects are turned into Proto
- expressions in this domain. The resulting expression object is suitable for storage
- in a local variable. In that scenario, it is usually preferable to return
- expressions by value; and, in the case of objects that are not yet Proto expressions,
- to wrap them by value (if possible) in a new Proto terminal expression. (Contrast
- this description with the description for
- <computeroutput><classname>proto::domain::as_child</classname></computeroutput>.)
- </para>
- <para>
- The <computeroutput>as_expr</computeroutput> function object turns objects into
- Proto expressions, if they are not already, by making them Proto terminals held by
- value if possible. Objects that are already Proto expressions are simply returned
- by value. If
- <computeroutput>wants_basic_expr<Generator>::value</computeroutput> is true,
- then let <emphasis>E</emphasis> be
- <computeroutput><classname>proto::basic_expr</classname></computeroutput>;
- otherwise, let <emphasis>E</emphasis> be
- <computeroutput><classname>proto::expr</classname></computeroutput>.
- Given an lvalue <computeroutput>t</computeroutput> of type
- <computeroutput>T</computeroutput>:
- <itemizedlist>
- <listitem>
- If <computeroutput>T</computeroutput> is not a Proto expression type, the resulting
- terminal is calculated as follows:
- <itemizedlist>
- <listitem>
- If <computeroutput>T</computeroutput> is a function type, an abstract type, or
- a type derived from <computeroutput>std::ios_base</computeroutput>, let
- <replaceable>A</replaceable> be <computeroutput>T &</computeroutput>.
- </listitem>
- <listitem>
- Otherwise, let <replaceable>A</replaceable> be the type
- <computeroutput>T</computeroutput> stripped of cv-qualifiers.
- </listitem>
- </itemizedlist>
- Then, the result of <computeroutput>as_expr<T>()(t)</computeroutput> is
- <computeroutput>Generator()(<replaceable>E</replaceable><tag::terminal,
- term< <replaceable>A</replaceable> > >::make(t))</computeroutput>.
- </listitem>
- <listitem>
- Otherwise, the result is <computeroutput>t</computeroutput> converted to an
- (un-const) rvalue.
- </listitem>
- </itemizedlist>
- </para>
- </description>
- <typedef name="result_type">
- <type><replaceable>see-below</replaceable></type>
- </typedef>
- <method-group name="public member functions">
- <method name="operator()" cv="const">
- <type>result_type</type>
- <parameter name="t">
- <paramtype>T &</paramtype>
- <description>
- <para>The object to wrap.</para>
- </description>
- </parameter>
- </method>
- </method-group>
- </struct>
- <struct name="as_child">
- <template>
- <template-type-parameter name="T"/>
- </template>
- <inherit><type><classname>proto::callable</classname></type></inherit>
- <purpose>
- A callable unary MonomorphicFunctionObject that specifies how objects are turned into
- Proto expressions in this domain, for use in scenarios where the resulting expression is
- intended to be made a child of another expression.
- </purpose>
- <description>
- <para>
- A unary MonomorphicFunctionObject that specifies how objects are turned into Proto
- expressions in this domain. The resulting expression object is suitable for storage
- as a child of another expression. In that scenario, it is usually
- preferable to store child expressions by reference; or, in the case of objects that
- are not yet Proto expressions, to wrap them by reference in a new Proto terminal
- expression. (Contrast this description with the description for
- <computeroutput><classname>proto::domain::as_expr</classname></computeroutput>.)
- </para>
- <para>
- The <computeroutput>as_child</computeroutput> function object turns objects into
- Proto expressions, if they are not already, by making them Proto terminals held by
- reference. Objects that are already Proto expressions are simply returned by
- reference. If
- <computeroutput>wants_basic_expr<Generator>::value</computeroutput> is true,
- then let <emphasis>E</emphasis> be
- <computeroutput><classname>proto::basic_expr</classname></computeroutput>;
- otherwise, let <emphasis>E</emphasis> be
- <computeroutput><classname>proto::expr</classname></computeroutput>.
- Given an lvalue <computeroutput>t</computeroutput> of type
- <computeroutput>T</computeroutput>:
- <itemizedlist>
- <listitem>
- If <computeroutput>T</computeroutput> is not a Proto expression type, the resulting
- terminal is
- <computeroutput>Generator()(<replaceable>E</replaceable><tag::terminal,
- term< <computeroutput>T &</computeroutput> > >::make(t))</computeroutput>.
- </listitem>
- <listitem>
- Otherwise, the result is the lvalue <computeroutput>t</computeroutput>.
- </listitem>
- </itemizedlist>
- </para>
- </description>
- <typedef name="result_type">
- <type><replaceable>see-below</replaceable></type>
- </typedef>
- <method-group name="public member functions">
- <method name="operator()" cv="const">
- <type>result_type</type>
- <parameter name="t">
- <paramtype>T &</paramtype>
- <description>
- <para>The object to wrap.</para>
- </description>
- </parameter>
- </method>
- </method-group>
- </struct>
- </struct>
- <!-- proto::default_domain -->
- <struct name="default_domain">
- <inherit><classname>proto::domain</classname><></inherit>
- <purpose>The domain expressions have by default, if <computeroutput>
- <classname alt="proto::extends">proto::extends<></classname></computeroutput> has not been used
- to associate a domain with an expression.</purpose>
- </struct>
- <!-- proto::basic_default_domain -->
- <struct name="basic_default_domain">
- <inherit><classname>proto::domain</classname>< <classname>proto::basic_default_generator</classname> ></inherit>
- <purpose>A domain similiar in purpose to <classname>proto::default_domain</classname>, except stating
- a preference for <classname>proto::basic_expr</classname><> over <classname>proto::expr</classname><>.</purpose>
- </struct>
- <!-- proto::deduce_domain -->
- <struct name="deduce_domain">
- <purpose>A pseudo-domain for use in functions and metafunctions that require a domain parameter.
- It indicates that the domain of the parent node should be inferred from the domains of the child nodes.</purpose>
- <description>
- <para>
- When <computeroutput>proto::deduce_domain</computeroutput> is used as a domain — either
- explicitly or implicitly by
- <computeroutput><functionname>proto::make_expr</functionname>()</computeroutput>,
- <computeroutput><functionname>proto::unpack_expr</functionname>()</computeroutput>,
- or Proto's operator overloads — Proto will use the domains of the child expressions to
- compute the domain of the parent. It is done in such a way that (A) expressions in domains
- that share a common super-domain are interoperable, and (B) expressions that are in
- the default domain (or a sub-domain thereof) are interoperable with <emphasis>all</emphasis>
- expressions. The rules are as follows:
- <itemizedlist>
- <listitem>
- A sub-domain is <emphasis>stronger</emphasis> than its super-domain.
- </listitem>
- <listitem>
- <computeroutput><classname>proto::default_domain</classname></computeroutput>,
- <computeroutput><classname>proto::basic_default_domain</classname></computeroutput>
- and all their sub-domains are <emphasis>weaker</emphasis> than all other domains.
- </listitem>
- <listitem>
- <computeroutput><classname>proto::basic_default_domain</classname></computeroutput>
- is weaker than
- <computeroutput><classname>proto::default_domain</classname></computeroutput>.
- </listitem>
- <listitem>
- For each child, define a set of domains <emphasis>S<subscript>N</subscript></emphasis>
- that includes the child's domain and all its super-domains.
- </listitem>
- <listitem>
- Define a set <emphasis>I<subscript>S</subscript></emphasis> that is the intersection of
- all the individual sets <emphasis>S<subscript>N</subscript></emphasis> that don't contain
- <computeroutput><classname>proto::default_domain</classname></computeroutput> or
- <computeroutput><classname>proto::basic_default_domain</classname></computeroutput>.
- </listitem>
- <listitem>
- Define a set <emphasis>I<subscript>W</subscript></emphasis> that is the intersection of
- all the individual sets <emphasis>S<subscript>N</subscript></emphasis> that contain
- <computeroutput><classname>proto::default_domain</classname></computeroutput> or
- <computeroutput><classname>proto::basic_default_domain</classname></computeroutput>.
- </listitem>
- <listitem>
- Define a set <emphasis>P</emphasis> that is the union of
- <emphasis>I<subscript>S</subscript></emphasis> and
- <emphasis>I<subscript>W</subscript></emphasis>.
- </listitem>
- <listitem>
- The common domain is the strongest domain in set <emphasis>P</emphasis>, with the
- following caveats.
- </listitem>
- <listitem>
- Let <emphasis>U</emphasis> be the union of all sets
- <emphasis>S<subscript>N</subscript></emphasis>. If the result is
- <computeroutput><classname>proto::default_domain</classname></computeroutput> or
- <computeroutput><classname>proto::basic_default_domain</classname></computeroutput>
- and <emphasis>U</emphasis> contains an element that is <emphasis>not </emphasis>
- <computeroutput><classname>proto::default_domain</classname></computeroutput> or
- <computeroutput><classname>proto::basic_default_domain</classname></computeroutput>,
- it is an error.
- </listitem>
- </itemizedlist>
- </para>
- <para>
- Note: the above description sounds like it would be expensive to compute at compile time.
- In fact, it can all be done using C++ function overloading.
- </para>
- </description>
- </struct>
- <!-- proto::is_domain -->
- <struct name="is_domain">
- <template>
- <template-type-parameter name="T"/>
- </template>
- <inherit>
- <type>mpl::bool_< <replaceable>true-or-false</replaceable> ></type>
- </inherit>
- <description>
- <para>
- A metafunction that returns <computeroutput>mpl::true_</computeroutput> if the type
- <computeroutput>T</computeroutput> is the type of a Proto domain;
- <computeroutput>mpl::false_</computeroutput> otherwise. If <computeroutput>T</computeroutput>
- inherits from <computeroutput><classname alt="proto::domain">proto::domain<></classname></computeroutput>,
- <computeroutput>is_domain<T></computeroutput> is <computeroutput>mpl::true_</computeroutput>.
- </para>
- </description>
- </struct>
- <!-- proto::domain_of -->
- <struct name="domain_of">
- <template>
- <template-type-parameter name="T"/>
- </template>
- <description>
- <para>
- A metafunction that returns the domain of a given type. If <computeroutput>T</computeroutput> is a Proto
- expression type, it returns that expression's associated domain. If not, it returns
- <computeroutput><classname>proto::default_domain</classname></computeroutput>.
- </para>
- </description>
- <typedef name="type">
- <type><replaceable>domain-of-T</replaceable></type>
- </typedef>
- </struct>
- <!-- proto::base_expr --><!--
- <struct name="base_expr">
- <template>
- <template-type-parameter name="Domain"/>
- <template-type-parameter name="Tag"/>
- <template-type-parameter name="Args"/>
- </template>
- <description>
- <para>
- Given a domain, a tag type and an argument list,
- compute the type of the expression to generate. This is
- either an instance of
- <computeroutput><classname>proto::basic_expr</classname><></computeroutput> or
- <computeroutput><classname>proto::expr</classname><></computeroutput>.
- </para>
- </description>
- <typedef name="A">
- <purpose>For exposition only</purpose>
- <type><classname>proto::basic_expr</classname>< Tag, Args ></type>
- </typedef>
- <typedef name="B">
- <purpose>For exposition only</purpose>
- <type><classname>proto::expr</classname>< Tag, Args ></type>
- </typedef>
- <typedef name="type">
- <type>typename mpl::if_<<classname>proto::wants_basic_expr</classname>< Domain >, A, B>::type</type>
- </typedef>
- </struct>-->
- </namespace>
- </namespace>
- </header>
|