Re: [proto] Held nodes by value for Fundamental types

2012-04-10 Thread Joel Falcou

On 10/04/2012 00:00, Eric Niebler wrote:

Thanks. I thought long about whether to handle the fundamental types
differently than user-defined types and decided against it. The
capture-everything-by-reference-by-default model is easy to explain and
reason about. Special cases can be handled on a per-domain basis as needed.


By-value capture of fundamental type is the classical way people do it 
in hand-made ET code. The ad-hoc support in proto is IMHO better as you 
may really want to capture reference and by the status of Proto of a 
EDSL toolkit, flexibility is really wanted :).


___
proto mailing list
proto@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/proto


Re: [proto] Held nodes by value for Fundamental types

2012-04-10 Thread Fernando Pelliccioni
On Tue, Apr 10, 2012 at 3:12 AM, Joel Falcou joel.fal...@lri.fr wrote:

 On 10/04/2012 00:00, Eric Niebler wrote:

 Thanks. I thought long about whether to handle the fundamental types
 differently than user-defined types and decided against it. The
 capture-everything-by-**reference-by-default model is easy to explain and
 reason about. Special cases can be handled on a per-domain basis as
 needed.


 By-value capture of fundamental type is the classical way people do it in
 hand-made ET code. The ad-hoc support in proto is IMHO better as you may
 really want to capture reference and by the status of Proto of a EDSL
 toolkit, flexibility is really wanted :).


Right. I agree with your opinion.

Maybe by defining another domain like default_domain_fundamental_by_value
(please don't use that name :-)).
Thus, the user saves typing as_child if all she/he is looking for is to
change this behavior.

Regards,
Fernando.
___
proto mailing list
proto@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/proto


[proto] Held nodes by value for Fundamental types

2012-04-09 Thread Fernando Pelliccioni
Hello,

I'm wondering if it would be appropriate to treat the fundamental types
(char, short, int, double, ...) by value, by default.

I wrote this simple piece of code.
I'm not sure if I'm leaving without considering any other implication, but
I think it may be an improvement.
Please, tell me if I am wrong.

Thanks and regards,
Fernando Pelliccioni.


//BEGIN CODE
**
#include boost/proto/proto.hpp

namespace math
{

template typename T
struct dynamic_matrix
{
  dynamic_matrix(std::size_t x_lenght, std::size_t y_lenght)
  {
//...
  }
  //Expensive Copy Constructor!!
  //...
};

}  // namespace math



using namespace boost;

//-

#define BOOST_PROTO_DEFINE_BINARY_OPERATOR_PRIMITIVE(OP, TAG, TRAIT,
DOMAIN, PRIMITIVE)\
  templatetypename Left
   \
  BOOST_FORCEINLINE
   \
  typename boost::proto::detail::enable_binary
   \
  DOMAIN
\
  , DOMAIN::proto_grammar
   \
  , BOOST_PROTO_APPLY_BINARY_(TRAIT, Left, PRIMITIVE)
   \
  , TAG
   \
  , Left const 
\
  , PRIMITIVE
   \
  ::type const
   \
  operator OP(Left left, PRIMITIVE right)
   \
  {
   \
  return boost::proto::detail::make_expr_TAG, DOMAIN, Left const ,
PRIMITIVE()(left, right);\
  }
   \
  templatetypename Right
\
  BOOST_FORCEINLINE
   \
  typename boost::proto::detail::enable_binary
   \
  DOMAIN
\
  , DOMAIN::proto_grammar
   \
  , BOOST_PROTO_APPLY_BINARY_(TRAIT, PRIMITIVE, Right)
\
  , TAG
   \
  , PRIMITIVE
   \
  , Right const 
   \
  ::type const
   \
  operator OP(PRIMITIVE left, Right right)
\
  {
   \
  return boost::proto::detail::make_expr_TAG, DOMAIN, PRIMITIVE, Right
const ()(left, right);   \
  }
  /**/

//-

namespace math
{
  template typename T
  struct is_terminal
: mpl::false_
  {};

  template typename U
  struct is_terminaldynamic_matrixU 
: mpl::true_
  {};

  BOOST_PROTO_DEFINE_OPERATORS(is_terminal, proto::default_domain)
  BOOST_PROTO_DEFINE_BINARY_OPERATOR_PRIMITIVE(*,
boost::proto::tag::multiplies, is_terminal, proto::default_domain, int)

} //namespace math


int main( /* int argc, char* argv[] */ )
{
  using math::dynamic_matrix;
  dynamic_matrixint m1(5, 5);   //define the x and y size of the
matrix
  dynamic_matrixint m2(5, 5);

  auto e = m1 + m2;   // m1 and m2 are held by reference
  auto e2 = m1 * m2;  // m1 and m2 are held by reference
  auto e3 = m1 * 5;   // m1 is held by reference. 5 is
held by value - NO dangling references
  auto e4 = proto::deep_copy(m1 * m2);// Expensive copy of m1 and m2
  auto e5 = proto::deep_copy(m1 * 5); // Expensive copy of m1
  auto e6 = m1 + m2 * 5;  // m1 and m2 are held by
reference. 5 is held by value - NO dangling references
  auto e7 = m1 + m2 + dynamic_matrixint(5, 5); //dangling reference - I
don't care - Needed deep_copy

  return 0;
}

//END CODE
**
___
proto mailing list
proto@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/proto


Re: [proto] Held nodes by value for Fundamental types

2012-04-09 Thread Eric Niebler
On 4/9/2012 2:21 PM, Fernando Pelliccioni wrote:
 Hello,
 
 I'm wondering if it would be appropriate to treat the fundamental types
 (char, short, int, double, ...) by value, by default.
 
 I wrote this simple piece of code.
 I'm not sure if I'm leaving without considering any other implication,
 but I think it may be an improvement.
 Please, tell me if I am wrong.

Thanks. I thought long about whether to handle the fundamental types
differently than user-defined types and decided against it. The
capture-everything-by-reference-by-default model is easy to explain and
reason about. Special cases can be handled on a per-domain basis as needed.

There is a way to change the capture behavior for your domain. The newly
released version of Proto documents how to do this (although the
functionality has been there for a few releases already).

http://www.boost.org/doc/libs/1_49_0/doc/html/proto/users_guide.html#boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.per_domain_as_child

In short, you'll need to define an as_child metafunction in your domain
definition:

class my_domain
  : proto::domain my_generator, my_grammar 
{
// Here is where you define how Proto should handle
// sub-expressions that are about to be glommed into
// a larger expression.
template typename T 
struct as_child
{
typedef unspecified-Proto-expr-type result_type;

result_type operator()( T  t ) const
{
return unspecified-Proto-expr-object;
}
};
};

In as_child, you'll have to do this (pseudocode):

if (is_exprT)
  return T 
else if(is_fundamentalT)
  return proto::terminalT::type
else
  return proto::terminalT ::type

The metaprogramming is left as an exercise. :-)

-- 
Eric Niebler
BoostPro Computing
http://www.boostpro.com
___
proto mailing list
proto@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/proto