
-----Original Message----- From: boost-users-bounces@lists.boost.org [mailto:boost-users-bounces@lists.boost.org] On Behalf Of Eric Niebler Sent: 05 February 2009 16:40 To: boost-users@lists.boost.org Subject: Re: [Boost-users] proto: analytical-only math functions
Question4: What is a quick way to test fundef_lhs_grammar does what I intend?
When I want to test a grammar, I define two functions like this:
template<typename E> void assert_matches( E const & ) { BOOST_MPL_ASSERT((proto::matches<E, fundef_lhs_grammar>)); }
template<typename E> void assert_not_matches( E const & ) { BOOST_MPL_ASSERT_NOT((proto::matches<E, fundef_lhs_grammar>)); }
Then in main(), I can create expressions and pass them to one of these functions. Either it matches or it doesn't, and I can find out at compile time. HTH,
The grammar of the LHS function definition seems correct. The compilation takes too long however (using here intel/msvc libs). See the main.cpp and includes below. Any ideas how to speed compile time up? Regards, --------------------------------------- main.cpp #include <boost/mpl/assert.hpp> #include "math.h" using namespace boost; using namespace mathtest; template<typename E> void assert_matches( E const & ) { BOOST_MPL_ASSERT((proto::matches<E, mathtest::fundef_lhs_grammar>)); } template<typename E> void assert_not_matches( E const & ) { BOOST_MPL_ASSERT_NOT((proto::matches<E, mathtest::fundef_lhs_grammar>)); } int main() { function2 f; assert_matches( f(x0,x1) ); assert_not_matches( f(x0,x1) ); return 0; } --------------------------------------- math.h #ifndef TEST_MATH_HPP #define TEST_MATH_HPP #include <boost/mpl/size_t.hpp> #include <boost/mpl/prior.hpp> #include <boost/proto/proto.hpp> #ifndef TEST_MATH_MAX_DIMENSION #define TEST_MATH_MAX_DIMENSION 100 #endif #include "constants.hpp" #include "variables.hpp" #include "basic_functions.hpp" #include "functions.hpp" namespace mathtest { using namespace boost; //// Valid expressions on the LHS of the = operator struct fundef_lhs_grammar : proto::or_< // lone functions are ok function_constant_proto_terminal , proto::and_< // f(x,y,z,...) is ok ... proto::function< proto::terminal< function_tag< proto::_ > > , proto::vararg< proto::terminal< variable_tag< proto::_ > >
> // ... as long as the dimension of the function // matches the number of arguments. , proto::if_< mpl::equal_to< dimension_of< proto::_value(proto::_child0) > , mpl::prior<proto::arity_of<proto::_> > >() > > > {}; } #endif //TEST_MATH_HPP --------------------------------------- functions.hpp #ifndef TEST_MATH_FUNCTIONS_HPP #define TEST_MATH_FUNCTIONS_HPP #include <boost/proto/proto.hpp> #include <boost/mpl/size_t.hpp> #include <boost/preprocessor/cat.hpp> #include <boost/preprocessor/iteration/local.hpp> namespace mathtest { using namespace boost; // to represent general functions of dimensions up to TEST_MATH_MAX_DIMENSION template <typename dim> struct function_tag { typedef dim dimension; }; typedef proto::terminal< function_tag< mpl::size_t<0> > > function_constant_proto_terminal; typedef function_constant_proto_terminal::type function_constant; // constant functions typedef proto::terminal< function_tag< mpl::size_t<1> > >::type function; // 1-variable functions #define BOOST_PP_LOCAL_LIMITS (0, TEST_MATH_MAX_DIMENSION) #define BOOST_PP_LOCAL_MACRO(n)\ BOOST_PP_CAT(\ BOOST_PP_CAT(\ BOOST_PP_CAT(\ typedef proto::terminal< function_tag< mpl::size_t<\ BOOST_PP_CAT(n,> > >::type function)\ ), n ), ;) ??=include BOOST_PP_LOCAL_ITERATE() // Numerical metafunction that returns the dimensionality of a mathtest::function_tag<dim> template<typename FunTag> struct dimension_of { typedef typename FunTag::dimension type; const static size_t value = type::value; }; } #endif // TEST_MATH_FUNCTIONS_HPP