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 ******************************************************************************************