Boost logo

Proto :

Subject: [proto] Held nodes by value for Fundamental types
From: Fernando Pelliccioni (fpelliccioni_at_[hidden])
Date: 2012-04-09 17:21:57


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) \
  template<typename 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); \
  }
                       \
  template<typename 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_terminal<dynamic_matrix<U> >
    : 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_matrix<int> m1(5, 5); //define the x and y size of the
matrix
  dynamic_matrix<int> 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_matrix<int>(5, 5); //dangling reference - I
don't care - Needed deep_copy

  return 0;
}

//END CODE
******************************************************************************************



Proto list run by eric at boostpro.com