|
Boost Users : |
Subject: Re: [Boost-users] proto: analytical-only math functions
From: Hicham Mouline (hicham_at_[hidden])
Date: 2009-02-07 08:03:56
-----Original Message-----
From: boost-users-bounces_at_[hidden]
[mailto:boost-users-bounces_at_[hidden]] On Behalf Of Eric Niebler
Sent: 05 February 2009 16:40
To: boost-users_at_[hidden]
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
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net