Edit: /usr/include/boost/proto/domain.hpp (11616B)
///////////////////////////////////////////////////////////////////////////////
/// \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
#include
#include
#include
#include
#include
#if defined(_MSC_VER)
# pragma warning(push)
# pragma warning(disable : 4714) // function 'xxx' marked as __forceinline not inlined
#endif
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 its super-domain, etc.).
///
/// Example:
/// \code
/// template
/// struct MyExpr;
///
/// struct MyGrammar
/// : or_< terminal<_>, plus >
/// {};
///
/// // Define MyDomain, in which all expressions are
/// // wrapped in MyExpr<> and only expressions that
/// // conform to MyGrammar are allowed.
/// struct MyDomain
/// : domain, MyGrammar>
/// {};
///
/// // Use MyDomain to define MyExpr
/// template
/// struct MyExpr
/// : extends, 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 as_expr\<\> 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 wants_basic_expr\::value 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 T &.
/// Otherwise, let \c A be the type \c T stripped of cv-qualifiers.
/// Then, the result of applying as_expr\()(t) is
/// Generator()(E\ \>::make(t)).
///
/// If \c T is a Proto expression type and its generator type is different from
/// \c Generator, the result is Generator()(t).
///
/// Otherwise, the result is \c t converted to an (un-const) rvalue.
///
template
struct as_expr
: detail::as_expr<
T
, typename detail::base_generator::type
, wants_basic_expr::value
>
{
BOOST_PROTO_CALLABLE()
};
/// INTERNAL ONLY
///
template
struct as_expr
{
BOOST_PROTO_CALLABLE()
typedef typename remove_const::type result_type;
BOOST_FORCEINLINE
result_type operator()(T &e) const
{
return e;
}
};
/// \brief A unary MonomorphicFunctionObject that turns objects into Proto
/// expression objects in this domain.
///
/// The as_child\<\> 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 wants_basic_expr\::value 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
/// Generator()(E\ \>::make(t)).
///
/// If \c T is a Proto expression type and its generator type is different from
/// \c Generator, the result is Generator()(t).
///
/// Otherwise, the result is the lvalue \c t.
///
template
struct as_child
: detail::as_child<
T
, typename detail::base_generator::type
, wants_basic_expr::value
>
{
BOOST_PROTO_CALLABLE()
};
/// INTERNAL ONLY
///
template
struct as_child
{
BOOST_PROTO_CALLABLE()
typedef T &result_type;
BOOST_FORCEINLINE
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
{};
/// \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
{};
/// \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
struct base_expr
{
typedef proto::expr type;
};
/// INTERNAL ONLY
///
template
struct base_expr
{
typedef proto::basic_expr 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\ is
/// \c mpl::true_.
template
struct is_domain
: mpl::false_
{};
/// INTERNAL ONLY
///
template
struct 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
struct domain_of
{
typedef default_domain type;
};
/// INTERNAL ONLY
///
template
struct domain_of
{
typedef typename T::proto_domain type;
};
/// INTERNAL ONLY
///
template
struct domain_of
{
typedef typename domain_of::type type;
};
/// INTERNAL ONLY
///
template
struct domain_of, void>
{
typedef typename domain_of::type type;
};
/// INTERNAL ONLY
///
template
struct domain_of const, void>
{
typedef typename domain_of::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
struct is_sub_domain_of
: is_sub_domain_of
{};
/// INTERNAL ONLY
///
template
struct is_sub_domain_of
: mpl::false_
{};
/// INTERNAL ONLY
///
template
struct is_sub_domain_of
: mpl::true_
{};
}}
#if defined(_MSC_VER)
# pragma warning(pop)
#endif
#endif