annotate DEPENDENCIES/generic/include/boost/proto/domain.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 ///////////////////////////////////////////////////////////////////////////////
Chris@16 2 /// \file domain.hpp
Chris@16 3 /// Contains definition of domain\<\> class template and helpers for
Chris@16 4 /// defining domains with a generator and a grammar for controlling
Chris@16 5 /// operator overloading.
Chris@16 6 //
Chris@16 7 // Copyright 2008 Eric Niebler. Distributed under the Boost
Chris@16 8 // Software License, Version 1.0. (See accompanying file
Chris@16 9 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 10
Chris@16 11 #ifndef BOOST_PROTO_DOMAIN_HPP_EAN_02_13_2007
Chris@16 12 #define BOOST_PROTO_DOMAIN_HPP_EAN_02_13_2007
Chris@16 13
Chris@16 14 #include <boost/ref.hpp>
Chris@16 15 #include <boost/type_traits/is_same.hpp>
Chris@16 16 #include <boost/proto/proto_fwd.hpp>
Chris@16 17 #include <boost/proto/generate.hpp>
Chris@16 18 #include <boost/proto/detail/as_expr.hpp>
Chris@16 19 #include <boost/proto/detail/deduce_domain.hpp>
Chris@16 20
Chris@101 21 #if defined(_MSC_VER)
Chris@16 22 # pragma warning(push)
Chris@16 23 # pragma warning(disable : 4714) // function 'xxx' marked as __forceinline not inlined
Chris@16 24 #endif
Chris@16 25
Chris@16 26 namespace boost { namespace proto
Chris@16 27 {
Chris@16 28
Chris@16 29 namespace detail
Chris@16 30 {
Chris@16 31 struct not_a_generator
Chris@16 32 {};
Chris@16 33
Chris@16 34 struct not_a_grammar
Chris@16 35 {};
Chris@16 36
Chris@16 37 struct not_a_domain
Chris@16 38 {};
Chris@16 39 }
Chris@16 40
Chris@16 41 namespace domainns_
Chris@16 42 {
Chris@16 43 /// \brief For use in defining domain tags to be used
Chris@16 44 /// with \c proto::extends\<\>. A \e Domain associates
Chris@16 45 /// an expression type with a \e Generator, and optionally
Chris@16 46 /// a \e Grammar.
Chris@16 47 ///
Chris@16 48 /// The Generator determines how new expressions in the
Chris@16 49 /// domain are constructed. Typically, a generator wraps
Chris@16 50 /// all new expressions in a wrapper that imparts
Chris@16 51 /// domain-specific behaviors to expressions within its
Chris@16 52 /// domain. (See \c proto::extends\<\>.)
Chris@16 53 ///
Chris@16 54 /// The Grammar determines whether a given expression is
Chris@16 55 /// valid within the domain, and automatically disables
Chris@16 56 /// any operator overloads which would cause an invalid
Chris@16 57 /// expression to be created. By default, the Grammar
Chris@16 58 /// parameter defaults to the wildcard, \c proto::_, which
Chris@16 59 /// makes all expressions valid within the domain.
Chris@16 60 ///
Chris@16 61 /// The Super declares the domain currently being defined
Chris@16 62 /// to be a sub-domain of Super. Expressions in sub-domains
Chris@16 63 /// can be freely combined with expressions in its super-
Chris@16 64 /// domain (and <I>its</I> super-domain, etc.).
Chris@16 65 ///
Chris@16 66 /// Example:
Chris@16 67 /// \code
Chris@16 68 /// template<typename Expr>
Chris@16 69 /// struct MyExpr;
Chris@16 70 ///
Chris@16 71 /// struct MyGrammar
Chris@16 72 /// : or_< terminal<_>, plus<MyGrammar, MyGrammar> >
Chris@16 73 /// {};
Chris@16 74 ///
Chris@16 75 /// // Define MyDomain, in which all expressions are
Chris@16 76 /// // wrapped in MyExpr<> and only expressions that
Chris@16 77 /// // conform to MyGrammar are allowed.
Chris@16 78 /// struct MyDomain
Chris@16 79 /// : domain<generator<MyExpr>, MyGrammar>
Chris@16 80 /// {};
Chris@16 81 ///
Chris@16 82 /// // Use MyDomain to define MyExpr
Chris@16 83 /// template<typename Expr>
Chris@16 84 /// struct MyExpr
Chris@16 85 /// : extends<Expr, MyExpr<Expr>, MyDomain>
Chris@16 86 /// {
Chris@16 87 /// // ...
Chris@16 88 /// };
Chris@16 89 /// \endcode
Chris@16 90 ///
Chris@16 91 template<
Chris@16 92 typename Generator // = default_generator
Chris@16 93 , typename Grammar // = proto::_
Chris@16 94 , typename Super // = no_super_domain
Chris@16 95 >
Chris@16 96 struct domain
Chris@16 97 : Generator
Chris@16 98 {
Chris@16 99 typedef Generator proto_generator;
Chris@16 100 typedef Grammar proto_grammar;
Chris@16 101 typedef Super proto_super_domain;
Chris@16 102 typedef domain proto_base_domain;
Chris@16 103
Chris@16 104 /// INTERNAL ONLY
Chris@16 105 typedef void proto_is_domain_;
Chris@16 106
Chris@16 107 /// \brief A unary MonomorphicFunctionObject that turns objects into Proto
Chris@16 108 /// expression objects in this domain.
Chris@16 109 ///
Chris@16 110 /// The <tt>as_expr\<\></tt> function object turns objects into Proto expressions, if
Chris@16 111 /// they are not already, by making them Proto terminals held by value if
Chris@16 112 /// possible. Objects that are already Proto expressions are left alone.
Chris@16 113 ///
Chris@16 114 /// If <tt>wants_basic_expr\<Generator\>::value</tt> is true, then let \c E be \c basic_expr;
Chris@16 115 /// otherwise, let \t E be \c expr. Given an lvalue \c t of type \c T:
Chris@16 116 ///
Chris@16 117 /// If \c T is not a Proto expression type the resulting terminal is
Chris@16 118 /// calculated as follows:
Chris@16 119 ///
Chris@16 120 /// If \c T is a function type, an abstract type, or a type derived from
Chris@16 121 /// \c std::ios_base, let \c A be <tt>T &</tt>.
Chris@16 122 /// Otherwise, let \c A be the type \c T stripped of cv-qualifiers.
Chris@16 123 /// Then, the result of applying <tt>as_expr\<T\>()(t)</tt> is
Chris@16 124 /// <tt>Generator()(E\<tag::terminal, term\<A\> \>::make(t))</tt>.
Chris@16 125 ///
Chris@16 126 /// If \c T is a Proto expression type and its generator type is different from
Chris@16 127 /// \c Generator, the result is <tt>Generator()(t)</tt>.
Chris@16 128 ///
Chris@16 129 /// Otherwise, the result is \c t converted to an (un-const) rvalue.
Chris@16 130 ///
Chris@16 131 template<typename T, typename IsExpr = void, typename Callable = proto::callable>
Chris@16 132 struct as_expr
Chris@16 133 : detail::as_expr<
Chris@16 134 T
Chris@16 135 , typename detail::base_generator<Generator>::type
Chris@16 136 , wants_basic_expr<Generator>::value
Chris@16 137 >
Chris@16 138 {
Chris@16 139 BOOST_PROTO_CALLABLE()
Chris@16 140 };
Chris@16 141
Chris@16 142 /// INTERNAL ONLY
Chris@16 143 ///
Chris@16 144 template<typename T>
Chris@16 145 struct as_expr<T, typename T::proto_is_expr_, proto::callable>
Chris@16 146 {
Chris@16 147 BOOST_PROTO_CALLABLE()
Chris@16 148 typedef typename remove_const<T>::type result_type;
Chris@16 149
Chris@16 150 BOOST_FORCEINLINE
Chris@16 151 result_type operator()(T &e) const
Chris@16 152 {
Chris@16 153 return e;
Chris@16 154 }
Chris@16 155 };
Chris@16 156
Chris@16 157 /// \brief A unary MonomorphicFunctionObject that turns objects into Proto
Chris@16 158 /// expression objects in this domain.
Chris@16 159 ///
Chris@16 160 /// The <tt>as_child\<\></tt> function object turns objects into Proto expressions, if
Chris@16 161 /// they are not already, by making them Proto terminals held by reference.
Chris@16 162 /// Objects that are already Proto expressions are simply returned by reference.
Chris@16 163 ///
Chris@16 164 /// If <tt>wants_basic_expr\<Generator\>::value</tt> is true, then let \c E be \c basic_expr;
Chris@16 165 /// otherwise, let \t E be \c expr. Given an lvalue \c t of type \c T:
Chris@16 166 ///
Chris@16 167 /// If \c T is not a Proto expression type the resulting terminal is
Chris@16 168 /// <tt>Generator()(E\<tag::terminal, term\<T &\> \>::make(t))</tt>.
Chris@16 169 ///
Chris@16 170 /// If \c T is a Proto expression type and its generator type is different from
Chris@16 171 /// \c Generator, the result is <tt>Generator()(t)</tt>.
Chris@16 172 ///
Chris@16 173 /// Otherwise, the result is the lvalue \c t.
Chris@16 174 ///
Chris@16 175 template<typename T, typename IsExpr = void, typename Callable = proto::callable>
Chris@16 176 struct as_child
Chris@16 177 : detail::as_child<
Chris@16 178 T
Chris@16 179 , typename detail::base_generator<Generator>::type
Chris@16 180 , wants_basic_expr<Generator>::value
Chris@16 181 >
Chris@16 182 {
Chris@16 183 BOOST_PROTO_CALLABLE()
Chris@16 184 };
Chris@16 185
Chris@16 186 /// INTERNAL ONLY
Chris@16 187 ///
Chris@16 188 template<typename T>
Chris@16 189 struct as_child<T, typename T::proto_is_expr_, proto::callable>
Chris@16 190 {
Chris@16 191 BOOST_PROTO_CALLABLE()
Chris@16 192 typedef T &result_type;
Chris@16 193
Chris@16 194 BOOST_FORCEINLINE
Chris@16 195 result_type operator()(T &e) const
Chris@16 196 {
Chris@16 197 return e;
Chris@16 198 }
Chris@16 199 };
Chris@16 200 };
Chris@16 201
Chris@16 202 /// \brief The domain expressions have by default, if
Chris@16 203 /// \c proto::extends\<\> has not been used to associate
Chris@16 204 /// a domain with an expression.
Chris@16 205 ///
Chris@16 206 struct default_domain
Chris@16 207 : domain<>
Chris@16 208 {};
Chris@16 209
Chris@16 210 /// \brief A domain to use when you prefer the use of
Chris@16 211 /// \c proto::basic_expr\<\> over \c proto::expr\<\>.
Chris@16 212 ///
Chris@16 213 struct basic_default_domain
Chris@16 214 : domain<basic_default_generator>
Chris@16 215 {};
Chris@16 216
Chris@16 217 /// \brief A pseudo-domain for use in functions and
Chris@16 218 /// metafunctions that require a domain parameter. It
Chris@16 219 /// indicates that the domain of the parent node should
Chris@16 220 /// be inferred from the domains of the child nodes.
Chris@16 221 ///
Chris@16 222 /// \attention \c deduce_domain is not itself a valid domain.
Chris@16 223 ///
Chris@16 224 struct deduce_domain
Chris@16 225 : domain<detail::not_a_generator, detail::not_a_grammar, detail::not_a_domain>
Chris@16 226 {};
Chris@16 227
Chris@16 228 /// \brief Given a domain, a tag type and an argument list,
Chris@16 229 /// compute the type of the expression to generate. This is
Chris@16 230 /// either an instance of \c proto::expr\<\> or
Chris@16 231 /// \c proto::basic_expr\<\>.
Chris@16 232 ///
Chris@16 233 template<typename Domain, typename Tag, typename Args, bool WantsBasicExpr>
Chris@16 234 struct base_expr
Chris@16 235 {
Chris@16 236 typedef proto::expr<Tag, Args, Args::arity> type;
Chris@16 237 };
Chris@16 238
Chris@16 239 /// INTERNAL ONLY
Chris@16 240 ///
Chris@16 241 template<typename Domain, typename Tag, typename Args>
Chris@16 242 struct base_expr<Domain, Tag, Args, true>
Chris@16 243 {
Chris@16 244 typedef proto::basic_expr<Tag, Args, Args::arity> type;
Chris@16 245 };
Chris@16 246
Chris@16 247 }
Chris@16 248
Chris@16 249 /// A metafunction that returns \c mpl::true_
Chris@16 250 /// if the type \c T is the type of a Proto domain;
Chris@16 251 /// \c mpl::false_ otherwise. If \c T inherits from
Chris@16 252 /// \c proto::domain\<\>, \c is_domain\<T\> is
Chris@16 253 /// \c mpl::true_.
Chris@16 254 template<typename T, typename Void /* = void*/>
Chris@16 255 struct is_domain
Chris@16 256 : mpl::false_
Chris@16 257 {};
Chris@16 258
Chris@16 259 /// INTERNAL ONLY
Chris@16 260 ///
Chris@16 261 template<typename T>
Chris@16 262 struct is_domain<T, typename T::proto_is_domain_>
Chris@16 263 : mpl::true_
Chris@16 264 {};
Chris@16 265
Chris@16 266 /// A metafunction that returns the domain of
Chris@16 267 /// a given type. If \c T is a Proto expression
Chris@16 268 /// type, it returns that expression's associated
Chris@16 269 /// domain. If not, it returns
Chris@16 270 /// \c proto::default_domain.
Chris@16 271 template<typename T, typename Void /* = void*/>
Chris@16 272 struct domain_of
Chris@16 273 {
Chris@16 274 typedef default_domain type;
Chris@16 275 };
Chris@16 276
Chris@16 277 /// INTERNAL ONLY
Chris@16 278 ///
Chris@16 279 template<typename T>
Chris@16 280 struct domain_of<T, typename T::proto_is_expr_>
Chris@16 281 {
Chris@16 282 typedef typename T::proto_domain type;
Chris@16 283 };
Chris@16 284
Chris@16 285 /// INTERNAL ONLY
Chris@16 286 ///
Chris@16 287 template<typename T>
Chris@16 288 struct domain_of<T &, void>
Chris@16 289 {
Chris@16 290 typedef typename domain_of<T>::type type;
Chris@16 291 };
Chris@16 292
Chris@16 293 /// INTERNAL ONLY
Chris@16 294 ///
Chris@16 295 template<typename T>
Chris@16 296 struct domain_of<boost::reference_wrapper<T>, void>
Chris@16 297 {
Chris@16 298 typedef typename domain_of<T>::type type;
Chris@16 299 };
Chris@16 300
Chris@16 301 /// INTERNAL ONLY
Chris@16 302 ///
Chris@16 303 template<typename T>
Chris@16 304 struct domain_of<boost::reference_wrapper<T> const, void>
Chris@16 305 {
Chris@16 306 typedef typename domain_of<T>::type type;
Chris@16 307 };
Chris@16 308
Chris@16 309 /// A metafunction that returns \c mpl::true_
Chris@16 310 /// if the type \c SubDomain is a sub-domain of
Chris@16 311 /// \c SuperDomain; \c mpl::false_ otherwise.
Chris@16 312 template<typename SubDomain, typename SuperDomain>
Chris@16 313 struct is_sub_domain_of
Chris@16 314 : is_sub_domain_of<typename SubDomain::proto_super_domain, SuperDomain>
Chris@16 315 {};
Chris@16 316
Chris@16 317 /// INTERNAL ONLY
Chris@16 318 ///
Chris@16 319 template<typename SuperDomain>
Chris@16 320 struct is_sub_domain_of<proto::no_super_domain, SuperDomain>
Chris@16 321 : mpl::false_
Chris@16 322 {};
Chris@16 323
Chris@16 324 /// INTERNAL ONLY
Chris@16 325 ///
Chris@16 326 template<typename SuperDomain>
Chris@16 327 struct is_sub_domain_of<SuperDomain, SuperDomain>
Chris@16 328 : mpl::true_
Chris@16 329 {};
Chris@16 330
Chris@16 331 }}
Chris@16 332
Chris@101 333 #if defined(_MSC_VER)
Chris@16 334 # pragma warning(pop)
Chris@16 335 #endif
Chris@16 336
Chris@16 337 #endif