|
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