1 ///////////////////////////////////////////////////////////////////////////////
3 /// Contains definition of domain\<\> class template and helpers for
4 /// defining domains with a generator and a grammar for controlling
5 /// operator overloading.
7 // Copyright 2008 Eric Niebler. Distributed under the Boost
8 // Software License, Version 1.0. (See accompanying file
9 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
11 #ifndef BOOST_PROTO_DOMAIN_HPP_EAN_02_13_2007
12 #define BOOST_PROTO_DOMAIN_HPP_EAN_02_13_2007
14 #include <boost/proto/detail/prefix.hpp>
15 #include <boost/ref.hpp>
16 #include <boost/mpl/bool.hpp>
17 #include <boost/proto/proto_fwd.hpp>
18 #include <boost/proto/generate.hpp>
19 #include <boost/proto/detail/suffix.hpp>
21 namespace boost
{ namespace proto
26 struct not_a_generator
33 BOOST_PROTO_BEGIN_ADL_NAMESPACE(domainns_
)
35 /// \brief For use in defining domain tags to be used
36 /// with \c proto::extends\<\>. A \e Domain associates
37 /// an expression type with a \e Generator, and optionally
40 /// The Generator determines how new expressions in the
41 /// domain are constructed. Typically, a generator wraps
42 /// all new expressions in a wrapper that imparts
43 /// domain-specific behaviors to expressions within its
44 /// domain. (See \c proto::extends\<\>.)
46 /// The Grammar determines whether a given expression is
47 /// valid within the domain, and automatically disables
48 /// any operator overloads which would cause an invalid
49 /// expression to be created. By default, the Grammar
50 /// parameter defaults to the wildcard, \c proto::_, which
51 /// makes all expressions valid within the domain.
55 /// template<typename Expr>
59 /// : or_< terminal<_>, plus<MyGrammar, MyGrammar> >
62 /// // Define MyDomain, in which all expressions are
63 /// // wrapped in MyExpr<> and only expressions that
64 /// // conform to MyGrammar are allowed.
66 /// : domain<generator<MyExpr>, MyGrammar>
69 /// // Use MyDomain to define MyExpr
70 /// template<typename Expr>
72 /// : extends<Expr, MyExpr<Expr>, MyDomain>
79 typename Generator
BOOST_PROTO_WHEN_BUILDING_DOCS(= default_generator
)
80 , typename Grammar
BOOST_PROTO_WHEN_BUILDING_DOCS(= proto::_
)
85 typedef Grammar proto_grammar
;
88 typedef void proto_is_domain_
;
91 /// \brief The domain expressions have by default, if
92 /// \c proto::extends\<\> has not been used to associate
93 /// a domain with an expression.
99 /// \brief A pseudo-domain for use in functions and
100 /// metafunctions that require a domain parameter. It
101 /// indicates that the domain of the parent node should
102 /// be inferred from the domains of the child nodes.
104 /// \attention \c deduce_domain is not itself a valid domain.
107 : domain
<detail::not_a_generator
, detail::not_a_grammar
>
110 BOOST_PROTO_END_ADL_NAMESPACE(domainns_
)
114 /// A metafunction that returns \c mpl::true_
115 /// if the type \c T is the type of a Proto domain;
116 /// \c mpl::false_ otherwise. If \c T inherits from
117 /// \c proto::domain\<\>, \c is_domain\<T\> is
119 template<typename T
, typename Void
BOOST_PROTO_WHEN_BUILDING_DOCS(= void)>
127 struct is_domain
<T
, typename
T::proto_is_domain_
>
131 /// A metafunction that returns the domain of
132 /// a given type. If \c T is a Proto expression
133 /// type, it returns that expression's associated
134 /// domain. If not, it returns
135 /// \c proto::default_domain.
136 template<typename T
, typename Void
BOOST_PROTO_WHEN_BUILDING_DOCS(= void)>
139 typedef default_domain type
;
145 struct domain_of
<T
, typename
T::proto_is_expr_
>
147 typedef typename
T::proto_domain type
;
153 struct domain_of
<T
&, void>
155 typedef typename domain_of
<T
>::type type
;
161 struct domain_of
<boost::reference_wrapper
<T
>, void>
163 typedef typename domain_of
<T
>::type type
;
169 struct domain_of
<boost::reference_wrapper
<T
> const, void>
171 typedef typename domain_of
<T
>::type type
;