1 /////////////////////////////////////////////////////////////////////////////// 2 /// \file domain.hpp 3 /// Contains definition of domain\<\> class template and helpers for 4 /// defining domains with a generator and a grammar for controlling 5 /// operator overloading. 6 // 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) 10 11 #ifndef BOOST_PROTO_DOMAIN_HPP_EAN_02_13_2007 12 #define BOOST_PROTO_DOMAIN_HPP_EAN_02_13_2007 13 14 #include <boost/xpressive/proto/detail/prefix.hpp> 15 #include <boost/ref.hpp> 16 #include <boost/mpl/bool.hpp> 17 #include <boost/xpressive/proto/proto_fwd.hpp> 18 #include <boost/xpressive/proto/generate.hpp> 19 #include <boost/xpressive/proto/detail/suffix.hpp> 20 21 namespace boost { namespace proto 22 { 23 24 namespace detail 25 { 26 struct not_a_generator 27 {}; 28 29 struct not_a_grammar 30 {}; 31 } 32 33 namespace domainns_ 34 { 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 38 /// a \e Grammar. 39 /// 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\<\>.) 45 /// 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. 52 /// 53 /// Example: 54 /// \code 55 /// template<typename Expr> 56 /// struct MyExpr; 57 /// 58 /// struct MyGrammar 59 /// : or_< terminal<_>, plus<MyGrammar, MyGrammar> > 60 /// {}; 61 /// 62 /// // Define MyDomain, in which all expressions are 63 /// // wrapped in MyExpr<> and only expressions that 64 /// // conform to MyGrammar are allowed. 65 /// struct MyDomain 66 /// : domain<generator<MyExpr>, MyGrammar> 67 /// {}; 68 /// 69 /// // Use MyDomain to define MyExpr 70 /// template<typename Expr> 71 /// struct MyExpr 72 /// : extends<Expr, MyExpr<Expr>, MyDomain> 73 /// { 74 /// // ... 75 /// }; 76 /// \endcode 77 /// 78 template< 79 typename Generator BOOST_PROTO_FOR_DOXYGEN_ONLY(= default_generator) 80 , typename Grammar BOOST_PROTO_FOR_DOXYGEN_ONLY(= proto::_) 81 > 82 struct domain 83 : Generator 84 { 85 typedef Grammar proto_grammar; 86 typedef void proto_is_domain_; 87 }; 88 89 /// \brief The domain expressions have by default, if 90 /// \c proto::extends\<\> has not been used to associate 91 /// a domain with an expression. 92 /// 93 struct default_domain 94 : domain<> 95 {}; 96 97 /// \brief A pseudo-domain for use in functions and 98 /// metafunctions that require a domain parameter. It 99 /// indicates that the domain of the parent node should 100 /// be inferred from the domains of the children nodes. 101 /// 102 /// \attention \c deduce_domain is not itself a valid domain. 103 /// 104 struct deduce_domain 105 : domain<detail::not_a_generator, detail::not_a_grammar> 106 {}; 107 } 108 109 namespace result_of 110 { 111 /// A metafunction that returns \c mpl::true_ 112 /// if the type \c T is the type of a Proto domain; 113 /// \c mpl::false_ otherwise. If \c T inherits from 114 /// \c proto::domain\<\>, \c is_domain\<T\> is 115 /// \c mpl::true_. 116 template<typename T, typename Void BOOST_PROTO_FOR_DOXYGEN_ONLY(= void)> 117 struct is_domain 118 : mpl::false_ 119 {}; 120 121 /// INTERNAL ONLY 122 /// 123 template<typename T> 124 struct is_domain<T, typename T::proto_is_domain_> 125 : mpl::true_ 126 {}; 127 128 /// A metafunction that returns the domain of 129 /// a given type. If \c T is a Proto expression 130 /// type, it returns that expression's associated 131 /// domain. If not, it returns 132 /// \c proto::default_domain. 133 template<typename T, typename Void BOOST_PROTO_FOR_DOXYGEN_ONLY(= void)> 134 struct domain_of 135 { 136 typedef default_domain type; 137 }; 138 139 /// INTERNAL ONLY 140 /// 141 template<typename T> 142 struct domain_of<T, typename T::proto_is_expr_> 143 { 144 typedef typename T::proto_domain type; 145 }; 146 147 /// INTERNAL ONLY 148 /// 149 template<typename T> 150 struct domain_of<T &, void> 151 { 152 typedef typename domain_of<T>::type type; 153 }; 154 155 /// INTERNAL ONLY 156 /// 157 template<typename T> 158 struct domain_of<boost::reference_wrapper<T>, void> 159 { 160 typedef typename domain_of<T>::type type; 161 }; 162 163 /// INTERNAL ONLY 164 /// 165 template<typename T> 166 struct domain_of<boost::reference_wrapper<T> const, void> 167 { 168 typedef typename domain_of<T>::type type; 169 }; 170 } 171 }} 172 173 #endif 174