Added boost header
This commit is contained in:
326
test/external/boost/proto/domain.hpp
vendored
Normal file
326
test/external/boost/proto/domain.hpp
vendored
Normal file
@@ -0,0 +1,326 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// \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 domain to use when you prefer the use of
|
||||
/// \c proto::basic_expr\<\> over \c proto::expr\<\>.
|
||||
///
|
||||
struct basic_default_domain
|
||||
: domain<basic_default_generator>
|
||||
{};
|
||||
|
||||
/// \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
|
||||
Reference in New Issue
Block a user