I need a transform property_b that evaluates another transform property_a and returns what property_a returns+1. Simple enough, here's what I do: struct property_a : proto::or_< proto::when< proto::terminal<_>, mpl::int_<42>()>
{};
struct property_b : proto::or_ < proto::when< _, mpl::next<property_a(_) >() >
{};
The complete file is attached at the end of this message as "Working example". But when I move to my real application (of which I attach a very condensed version as "Non-working example") I cannot manage to make it compile. The code in #ifdef BUG...#endif gives an error, the #else branch doesn't (but doesn't compute what I need, which makes the fact it compiles secondary). I cannot see differences, other than my terminals now being in their own domain. H E L P TIA, Maurizio --=-=-= Content-Type: text/x-c++src Content-Disposition: inline; filename=test_transforms.cpp Content-Description: Working example #include <iostream> #include <boost/mpl/int.hpp> #include <boost/mpl/assert.hpp> #include <boost/mpl/min_max.hpp> #include <boost/proto/core.hpp> #include <boost/proto/context.hpp> #include <boost/proto/transform.hpp> namespace mpl = boost::mpl; namespace proto = boost::proto; using proto::_; template<typename T> struct data { typedef T type; }; proto::terminal<data<mpl::int_<42> > >::type a; struct property_a : proto::or_< proto::when< proto::terminal<_>, mpl::int_<42>()>
{};
struct property_b : proto::or_ < // proto::when< _, property_a> proto::when< _, mpl::next<property_a(_) >() >
{};
int main(int argc, char *argv[]) { std::cout << "property A = " << property_a () (a) << std::endl; std::cout << "property B = " << property_b () (a) << std::endl; return 0; } /// Local Variables: /// mode:c++ /// comment-column:60 /// fill-column:150 /// compile-command:"g++ -I. -I./boost -o test_transforms test_transforms.cpp" /// c-macro-cppflags:"-C -I. -I./boost" /// c-backslash-column:120 /// c-backslash-max-column:149 /// End: --=-=-= Content-Type: text/x-c++src Content-Disposition: inline; filename=width.cpp Content-Description: Non-working example //* Includes #include <iostream> //#include <iomanip> //#include <sstream> #include <limits.h> #define BOOST_PROTO_MAX_LOGICAL_ARITY 15 #include <boost/proto/proto.hpp> #include <boost/utility.hpp> // for enable_if #include <boost/mpl/min_max.hpp> #include <boost/type_traits/is_same.hpp> #include <boost/type_traits/is_arithmetic.hpp> #include <boost/integer_traits.hpp> #include <boost/mpl/assert.hpp> #include <boost/typeof/typeof.hpp> namespace quicksilver { namespace mpl = boost::mpl; namespace fusion = boost::fusion; namespace proto = boost::proto; using proto::_; template<typename E> class my_expression; template<typename R> struct data; template<typename B> struct representation_traits; template<int L, int R> struct bounds_c; template<typename E> int left (const E&); // template<typename E> struct result_of_expression; // template<typename E> struct representation_of_expression; struct actual_width_transform; struct unspecified {}; struct builtin_types_grammar : proto::or_ < proto::terminal<bool>, proto::terminal<int>, proto::terminal<unsigned int>, proto::terminal<long>, proto::terminal<unsigned long>, proto::terminal<long long>, proto::terminal<unsigned long long> > {}; struct my_grammar : proto::or_ < proto::terminal<data<_> >, proto::unary_expr<_, my_grammar>, proto::binary_expr<_, my_grammar, my_grammar>, builtin_types_grammar
{};
struct my_domain : proto::domain<proto::generator<my_expression>, struct my_grammar> {}; template <typename Expr> struct my_expression : proto::extends<Expr, my_expression<Expr>, my_domain> { typedef proto::extends<Expr, my_expression<Expr>, my_domain> base_type; my_expression (Expr const& expr_ = Expr()) : base_type (expr_) {} }; struct left_bound_transform : proto::or_< proto::when<proto::terminal<data<_> >, mpl::int_<42>() > > {}; struct actual_width_transform : proto::or_< //#define BUG #ifdef BUG mpl::next<left_bound_transform (_)>() #else left_bound_transform #endif
{}; template<typename L, typename R, typename I=short> struct bounds { typedef L meta_left; }; template<int L, int R> struct bounds_c : bounds<mpl::int_<L>, mpl::int_<R> > {}; template<typename Bounds> struct representation_traits { typedef Bounds bounds; }; template<typename R> struct data : R::bounds { typedef R representation; }; template<typename R> struct number : my_expression<typename proto::terminal<data<R> >::type> { typedef my_expression<typename proto::terminal<data<R> >::type> base_type; number () : base_type (base_type::proto_base_expr::make (data<R> ())) {} }; } // end of namespace quicksilver #include <boost/test/included/unit_test_framework.hpp> using namespace boost::unit_test; using namespace quicksilver; void test_width_transform () { typedef number<representation_traits<bounds_c<6,0> > > number_type; number_type i7; BOOST_MPL_ASSERT ((proto::matches<number_type, left_bound_transform>)); BOOST_MPL_ASSERT ((proto::matches<number_type, actual_width_transform>)); std::cout << "left (i7) = " << left_bound_transform () (i7) << std::endl; BOOST_ASSERT (left_bound_transform () (i7) == 6); std::cout << "width (i7) = " << actual_width_transform () (i7) << std::endl; } test_suite* init_unit_test_suite (int, char**) { test_suite* test= BOOST_TEST_SUITE( "Quicksilver" ); test->add (BOOST_TEST_CASE (&test_width_transform)); return test; } /// Local Variables: /// mode:c++ /// comment-column:60 /// fill-column:150 /// compile-command:"g++ -I. -I./boost -o width width.cpp -lgmpxx -lgmp" /// c-macro-cppflags:"-C -I. -I./boost" /// c-backslash-column:120 /// c-backslash-max-column:149 /// End: --=-=-=--