diff options
author | Vlad Voicu <vladv@rosedu.org> | 2012-03-02 10:01:11 (GMT) |
---|---|---|
committer | Kevin Smith <git@kismith.co.uk> | 2012-03-09 15:04:05 (GMT) |
commit | 1c8cd160b79b6bbcec72042bdb104ba530508a93 (patch) | |
tree | cff302b81e74c557fbc9e30fd43144d981b613d0 /3rdParty/Boost/src/boost/proto/domain.hpp | |
parent | 2944711aefec9a9dd66052440bc4f921910dd780 (diff) | |
download | swift-contrib-1c8cd160b79b6bbcec72042bdb104ba530508a93.zip swift-contrib-1c8cd160b79b6bbcec72042bdb104ba530508a93.tar.bz2 |
Added spirit to bundled boost
Diffstat (limited to '3rdParty/Boost/src/boost/proto/domain.hpp')
-rw-r--r-- | 3rdParty/Boost/src/boost/proto/domain.hpp | 319 |
1 files changed, 319 insertions, 0 deletions
diff --git a/3rdParty/Boost/src/boost/proto/domain.hpp b/3rdParty/Boost/src/boost/proto/domain.hpp new file mode 100644 index 0000000..29626aa --- /dev/null +++ b/3rdParty/Boost/src/boost/proto/domain.hpp @@ -0,0 +1,319 @@ +/////////////////////////////////////////////////////////////////////////////// +/// \file domain.hpp +/// Contains definition of domain\<\> class template and helpers for +/// defining domains with a generator and a grammar for controlling +/// operator overloading. +// +// Copyright 2008 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) + +#ifndef BOOST_PROTO_DOMAIN_HPP_EAN_02_13_2007 +#define BOOST_PROTO_DOMAIN_HPP_EAN_02_13_2007 + +#include <boost/ref.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/proto/proto_fwd.hpp> +#include <boost/proto/generate.hpp> +#include <boost/proto/detail/as_expr.hpp> +#include <boost/proto/detail/deduce_domain.hpp> + +namespace boost { namespace proto +{ + + namespace detail + { + struct not_a_generator + {}; + + struct not_a_grammar + {}; + + struct not_a_domain + {}; + } + + namespace domainns_ + { + /// \brief For use in defining domain tags to be used + /// with \c proto::extends\<\>. A \e Domain associates + /// an expression type with a \e Generator, and optionally + /// a \e Grammar. + /// + /// The Generator determines how new expressions in the + /// domain are constructed. Typically, a generator wraps + /// all new expressions in a wrapper that imparts + /// domain-specific behaviors to expressions within its + /// domain. (See \c proto::extends\<\>.) + /// + /// The Grammar 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, \c proto::_, which + /// makes all expressions valid within the domain. + /// + /// The Super declares the domain currently being defined + /// to be a sub-domain of Super. Expressions in sub-domains + /// can be freely combined with expressions in its super- + /// domain (and <I>its</I> super-domain, etc.). + /// + /// Example: + /// \code + /// template<typename Expr> + /// struct MyExpr; + /// + /// struct MyGrammar + /// : or_< terminal<_>, plus<MyGrammar, MyGrammar> > + /// {}; + /// + /// // Define MyDomain, in which all expressions are + /// // wrapped in MyExpr<> and only expressions that + /// // conform to MyGrammar are allowed. + /// struct MyDomain + /// : domain<generator<MyExpr>, MyGrammar> + /// {}; + /// + /// // Use MyDomain to define MyExpr + /// template<typename Expr> + /// struct MyExpr + /// : extends<Expr, MyExpr<Expr>, MyDomain> + /// { + /// // ... + /// }; + /// \endcode + /// + template< + typename Generator // = default_generator + , typename Grammar // = proto::_ + , typename Super // = no_super_domain + > + struct domain + : Generator + { + typedef Generator proto_generator; + typedef Grammar proto_grammar; + typedef Super proto_super_domain; + typedef domain proto_base_domain; + + /// INTERNAL ONLY + typedef void proto_is_domain_; + + /// \brief A unary MonomorphicFunctionObject that turns objects into Proto + /// expression objects in this domain. + /// + /// The <tt>as_expr\<\></tt> 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 left alone. + /// + /// If <tt>wants_basic_expr\<Generator\>::value</tt> is true, then let \c E be \c basic_expr; + /// otherwise, let \t E be \c expr. Given an lvalue \c t of type \c T: + /// + /// If \c T is not a Proto expression type the resulting terminal is + /// calculated as follows: + /// + /// If \c T is a function type, an abstract type, or a type derived from + /// \c std::ios_base, let \c A be <tt>T &</tt>. + /// Otherwise, let \c A be the type \c T stripped of cv-qualifiers. + /// Then, the result of applying <tt>as_expr\<T\>()(t)</tt> is + /// <tt>Generator()(E\<tag::terminal, term\<A\> \>::make(t))</tt>. + /// + /// If \c T is a Proto expression type and its generator type is different from + /// \c Generator, the result is <tt>Generator()(t)</tt>. + /// + /// Otherwise, the result is \c t converted to an (un-const) rvalue. + /// + template<typename T, typename IsExpr = void, typename Callable = proto::callable> + struct as_expr + : detail::as_expr< + T + , typename detail::base_generator<Generator>::type + , wants_basic_expr<Generator>::value + > + { + BOOST_PROTO_CALLABLE() + }; + + /// INTERNAL ONLY + /// + template<typename T> + struct as_expr<T, typename T::proto_is_expr_, proto::callable> + { + BOOST_PROTO_CALLABLE() + typedef typename remove_const<T>::type result_type; + + result_type operator()(T &e) const + { + return e; + } + }; + + /// \brief A unary MonomorphicFunctionObject that turns objects into Proto + /// expression objects in this domain. + /// + /// The <tt>as_child\<\></tt> 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 <tt>wants_basic_expr\<Generator\>::value</tt> is true, then let \c E be \c basic_expr; + /// otherwise, let \t E be \c expr. Given an lvalue \c t of type \c T: + /// + /// If \c T is not a Proto expression type the resulting terminal is + /// <tt>Generator()(E\<tag::terminal, term\<T &\> \>::make(t))</tt>. + /// + /// If \c T is a Proto expression type and its generator type is different from + /// \c Generator, the result is <tt>Generator()(t)</tt>. + /// + /// Otherwise, the result is the lvalue \c t. + /// + template<typename T, typename IsExpr = void, typename Callable = proto::callable> + struct as_child + : detail::as_child< + T + , typename detail::base_generator<Generator>::type + , wants_basic_expr<Generator>::value + > + { + BOOST_PROTO_CALLABLE() + }; + + /// INTERNAL ONLY + /// + template<typename T> + struct as_child<T, typename T::proto_is_expr_, proto::callable> + { + BOOST_PROTO_CALLABLE() + typedef T &result_type; + + result_type operator()(T &e) const + { + return e; + } + }; + }; + + /// \brief The domain expressions have by default, if + /// \c proto::extends\<\> has not been used to associate + /// a domain with an expression. + /// + struct default_domain + : domain<> + {}; + + /// \brief 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. + /// + /// \attention \c deduce_domain is not itself a valid domain. + /// + struct deduce_domain + : domain<detail::not_a_generator, detail::not_a_grammar, detail::not_a_domain> + {}; + + /// \brief Given a domain, a tag type and an argument list, + /// compute the type of the expression to generate. This is + /// either an instance of \c proto::expr\<\> or + /// \c proto::basic_expr\<\>. + /// + template<typename Domain, typename Tag, typename Args, bool WantsBasicExpr> + struct base_expr + { + typedef proto::expr<Tag, Args, Args::arity> type; + }; + + /// INTERNAL ONLY + /// + template<typename Domain, typename Tag, typename Args> + struct base_expr<Domain, Tag, Args, true> + { + typedef proto::basic_expr<Tag, Args, Args::arity> type; + }; + + } + + /// A metafunction that returns \c mpl::true_ + /// if the type \c T is the type of a Proto domain; + /// \c mpl::false_ otherwise. If \c T inherits from + /// \c proto::domain\<\>, \c is_domain\<T\> is + /// \c mpl::true_. + template<typename T, typename Void /* = void*/> + struct is_domain + : mpl::false_ + {}; + + /// INTERNAL ONLY + /// + template<typename T> + struct is_domain<T, typename T::proto_is_domain_> + : mpl::true_ + {}; + + /// A metafunction that returns the domain of + /// a given type. If \c T is a Proto expression + /// type, it returns that expression's associated + /// domain. If not, it returns + /// \c proto::default_domain. + template<typename T, typename Void /* = void*/> + struct domain_of + { + typedef default_domain type; + }; + + /// INTERNAL ONLY + /// + template<typename T> + struct domain_of<T, typename T::proto_is_expr_> + { + typedef typename T::proto_domain type; + }; + + /// INTERNAL ONLY + /// + template<typename T> + struct domain_of<T &, void> + { + typedef typename domain_of<T>::type type; + }; + + /// INTERNAL ONLY + /// + template<typename T> + struct domain_of<boost::reference_wrapper<T>, void> + { + typedef typename domain_of<T>::type type; + }; + + /// INTERNAL ONLY + /// + template<typename T> + struct domain_of<boost::reference_wrapper<T> const, void> + { + typedef typename domain_of<T>::type type; + }; + + /// A metafunction that returns \c mpl::true_ + /// if the type \c SubDomain is a sub-domain of + /// \c SuperDomain; \c mpl::false_ otherwise. + template<typename SubDomain, typename SuperDomain> + struct is_sub_domain_of + : is_sub_domain_of<typename SubDomain::proto_super_domain, SuperDomain> + {}; + + /// INTERNAL ONLY + /// + template<typename SuperDomain> + struct is_sub_domain_of<proto::no_super_domain, SuperDomain> + : mpl::false_ + {}; + + /// INTERNAL ONLY + /// + template<typename SuperDomain> + struct is_sub_domain_of<SuperDomain, SuperDomain> + : mpl::true_ + {}; + +}} + +#endif |