Edit: /usr/include/boost/proto/generate.hpp (14467B)
///////////////////////////////////////////////////////////////////////////////
/// \file generate.hpp
/// Contains definition of generate\<\> class template, which end users can
/// specialize for generating domain-specific expression wrappers.
//
// 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_GENERATE_HPP_EAN_02_13_2007
#define BOOST_PROTO_GENERATE_HPP_EAN_02_13_2007
#include
#include
#include
#include
#include
#include
#include
#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
{
template
struct by_value_generator_;
template
struct by_value_generator_, 0> >
{
typedef
proto::expr<
Tag
, term::value_type>
, 0
>
type;
BOOST_FORCEINLINE
static type const call(proto::expr, 0> const &e)
{
type that = {e.child0};
return that;
}
};
template
struct by_value_generator_, 0> >
{
typedef
proto::basic_expr<
Tag
, term::value_type>
, 0
>
type;
BOOST_FORCEINLINE
static type const call(proto::basic_expr, 0> const &e)
{
type that = {e.child0};
return that;
}
};
// Include the other specializations of by_value_generator_
#include
}
/// \brief Annotate a generator to indicate that it would
/// prefer to be passed instances of \c proto::basic_expr\<\> rather
/// than \c proto::expr\<\>. use_basic_expr\ is
/// itself a generator.
///
template
struct use_basic_expr
: Generator
{
BOOST_PROTO_USE_BASIC_EXPR()
};
/// \brief A simple generator that passes an expression
/// through unchanged.
///
/// Generators are intended for use as the first template parameter
/// to the \c domain\<\> class template and control if and how
/// expressions within that domain are to be customized.
/// The \c default_generator makes no modifications to the expressions
/// passed to it.
struct default_generator
{
BOOST_PROTO_CALLABLE()
template
struct result;
template
struct result
{
typedef Expr type;
};
/// \param expr A Proto expression
/// \return expr
template
BOOST_FORCEINLINE
BOOST_PROTO_RETURN_TYPE_STRICT_LOOSE(Expr, Expr const &)
operator ()(Expr const &e) const
{
return e;
}
};
/// \brief A simple generator that passes an expression
/// through unchanged and specifies a preference for
/// \c proto::basic_expr\<\> over \c proto::expr\<\>.
///
/// Generators are intended for use as the first template parameter
/// to the \c domain\<\> class template and control if and how
/// expressions within that domain are to be customized.
/// The \c default_generator makes no modifications to the expressions
/// passed to it.
struct basic_default_generator
: proto::use_basic_expr
{};
/// \brief A generator that wraps expressions passed
/// to it in the specified extension wrapper.
///
/// Generators are intended for use as the first template parameter
/// to the \c domain\<\> class template and control if and how
/// expressions within that domain are to be customized.
/// \c generator\<\> wraps each expression passed to it in
/// the \c Extends\<\> wrapper.
template class Extends>
struct generator
{
BOOST_PROTO_CALLABLE()
BOOST_PROTO_USE_BASIC_EXPR()
template
struct result;
template
struct result
{
typedef Extends type;
};
template
struct result
{
typedef Extends type;
};
template
struct result
{
typedef Extends type;
};
/// \param expr A Proto expression
/// \return Extends(expr)
template
BOOST_FORCEINLINE
Extends operator ()(Expr const &e) const
{
return Extends(e);
}
};
/// \brief A generator that wraps expressions passed
/// to it in the specified extension wrapper and uses
/// aggregate initialization for the wrapper.
///
/// Generators are intended for use as the first template parameter
/// to the \c domain\<\> class template and control if and how
/// expressions within that domain are to be customized.
/// \c pod_generator\<\> wraps each expression passed to it in
/// the \c Extends\<\> wrapper, and uses aggregate initialzation
/// for the wrapped object.
template class Extends>
struct pod_generator
{
BOOST_PROTO_CALLABLE()
BOOST_PROTO_USE_BASIC_EXPR()
template
struct result;
template
struct result
{
typedef Extends type;
};
template
struct result
{
typedef Extends type;
};
template
struct result
{
typedef Extends type;
};
/// \param expr The expression to wrap
/// \return Extends\ that = {expr}; return that;
template
BOOST_FORCEINLINE
Extends operator ()(Expr const &e) const
{
Extends that = {e};
return that;
}
// Work-around for:
// https://connect.microsoft.com/VisualStudio/feedback/details/765449/codegen-stack-corruption-using-runtime-checks-when-aggregate-initializing-struct
#if BOOST_WORKAROUND(BOOST_MSVC, < 1800)
template
BOOST_FORCEINLINE
Extends > > operator ()(expr > const &e) const
{
Extends > > that;
proto::value(that.proto_expr_) = proto::value(e);
return that;
}
template
BOOST_FORCEINLINE
Extends > > operator ()(basic_expr > const &e) const
{
Extends > > that;
proto::value(that.proto_expr_) = proto::value(e);
return that;
}
#endif
};
/// \brief A generator that replaces child nodes held by
/// reference with ones held by value. Use with
/// \c compose_generators to forward that result to another
/// generator.
///
/// Generators are intended for use as the first template parameter
/// to the \c domain\<\> class template and control if and how
/// expressions within that domain are to be customized.
/// \c by_value_generator ensures all child nodes are
/// held by value. This generator is typically composed with a
/// second generator for further processing, as
/// compose_generators\.
struct by_value_generator
{
BOOST_PROTO_CALLABLE()
template
struct result;
template
struct result
{
typedef
typename detail::by_value_generator_::type
type;
};
template
struct result
{
typedef
typename detail::by_value_generator_::type
type;
};
template
struct result
{
typedef
typename detail::by_value_generator_::type
type;
};
/// \param expr The expression to modify.
/// \return deep_copy(expr)
template
BOOST_FORCEINLINE
typename result::type operator ()(Expr const &e) const
{
return detail::by_value_generator_::call(e);
}
};
/// \brief A composite generator that first applies one
/// transform to an expression and then forwards the result
/// on to another generator for further transformation.
///
/// Generators are intended for use as the first template parameter
/// to the \c domain\<\> class template and control if and how
/// expressions within that domain are to be customized.
/// \c compose_generators\<\> is a composite generator that first
/// applies one transform to an expression and then forwards the
/// result on to another generator for further transformation.
template
struct compose_generators
{
BOOST_PROTO_CALLABLE()
template
struct result;
template
struct result
{
typedef
typename Second::template result<
Second(typename First::template result::type)
>::type
type;
};
template
struct result
{
typedef
typename Second::template result<
Second(typename First::template result::type)
>::type
type;
};
template
struct result
{
typedef
typename Second::template result<
Second(typename First::template result::type)
>::type
type;
};
/// \param expr The expression to modify.
/// \return Second()(First()(expr))
template
BOOST_FORCEINLINE
typename result::type operator ()(Expr const &e) const
{
return Second()(First()(e));
}
};
/// \brief Tests a generator to see whether it would prefer
/// to be passed instances of \c proto::basic_expr\<\> rather than
/// \c proto::expr\<\>.
///
template
struct wants_basic_expr
: mpl::false_
{};
template
struct wants_basic_expr
: mpl::true_
{};
/// INTERNAL ONLY
template<>
struct is_callable
: mpl::true_
{};
/// INTERNAL ONLY
template class Extends>
struct is_callable >
: mpl::true_
{};
/// INTERNAL ONLY
template class Extends>
struct is_callable >
: mpl::true_
{};
/// INTERNAL ONLY
template<>
struct is_callable
: mpl::true_
{};
/// INTERNAL ONLY
template
struct is_callable >
: mpl::true_
{};
}}
// Specializations of boost::result_of and boost::tr1_result_of to eliminate
// some unnecessary template instantiations
namespace boost
{
template
struct result_of
{
typedef Expr type;
};
template
struct result_of
{
typedef Expr type;
};
template
struct result_of
{
typedef Expr type;
};
template
struct result_of
{
typedef Expr type;
};
#if BOOST_VERSION >= 104400
template
struct tr1_result_of
{
typedef Expr type;
};
template
struct tr1_result_of
{
typedef Expr type;
};
template
struct tr1_result_of
{
typedef Expr type;
};
template
struct tr1_result_of
{
typedef Expr type;
};
#endif
}
#if defined(_MSC_VER)
# pragma warning(pop)
#endif
#endif // BOOST_PROTO_GENERATE_HPP_EAN_02_13_2007