C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

common result_of for operations

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language, library and standards
View previous topic :: View next topic  
Author Message
kwikius
Guest





PostPosted: Fri Jul 09, 2004 5:45 am    Post subject: common result_of for operations Reply with quote



When working with different libraries it is quite common to find that
they have their own methods for determining the result_types of
operations.In nearly all cases the functionality is pretty much the
same.
Here Op is a template parameter representing the operation ie '+', '-'
etc.
A and B are my types. Hence in working with Your library I am doing
basically boilerplate:


your_library_namespace{

your_result_of<Op,MyUDTa,MyUDTb>{


typedef MyOp_implementation your_result_type;

};
}

I would like to propose that the Op name should be standardised in
std, to prevent the tedious replication of what is basically
boilerplate.

We already have the proposed result_of<F(A,B)>::type . All that is now
needed is standardisation of the name Op above for each operation.

Hence I propose this to relieve the tedium :

result_of<operator_plus(My_TypeA,MyTypeB)>::type
result_of<operator_divides(My_TypeA,MyTypeB)>::type
result_of<operator_multiplies(My_TypeA,MyTypeB)>::type

etcetera.


In other words one common interface for operations on UDT's and
fundamental types.

As further refinement implementation of classes representing
binary_operations, and unary operations. The point of this being that
though the above is a pretty interface, it is more work to specialise
individually per UDT. (One Impl shown at the end) The following is
quick.

template<typename L,template
struct binary_operation{
typedef Whatever result_type;
result_type operator()( /*by_const_ref_or_val*/ A,B )
};
template<template
struct unary_operation{
typedef Whatever result_type;
result_type operator()(...)
};
Here the template parameter is merely a key, which resolves to one of
the binary_functions in functional.

Hence a multiplication between an int and a double would look like
this:

binary_operation<int,multiplies,double>::result_type.

Both this and the individual operator_xx functions above play ok with
result_of:

result_of<binary_operation result_of<operator_multiplies(int,double)>::type // ok

The operator_multiplies interface does not then need to be
specialised per class but can use the implementation in
binary_operation and unary_operation:

template<template
struct operator_;

/* operator_ impl ... shown below */

// these just put here to get to the point

struct operator_logical_or : operator_<std::logical_or>{};
struct operator_logical_and : operator_<std::logical_and>{};

struct operator_equal_to : operator_<std::not_equal_to>{};
struct operator_not_equal_to : operator_<std::equal_to>{};
struct operator_greater_equal : operator_<std::greater_equal>{};
struct operator_less_equal : operator_<std::less_equal>{};
struct operator_greater : operator_<std::greater>{};
struct operator_less : operator_<std::less>{};
struct operator_minus : operator_<std::minus>{};
struct operator_plus : operator_<std::plus>{};
struct operator_multiplies : operator_<std::multiplies>{};
struct operator_divides : operator_<std::divides>{};

//possibly
struct operator_shift_left : operator_<shift_left>{};
struct operator_shift_right : operator_<shift_right>{};
struct operator_bit_or : operator_<bit_or>{}; //tbd
struct operator_bit_xor : operator_<bit_xor>{};
struct operator_bit_and : operator_<bit_and>{};

template<template
struct operator_{ //base class for operators

template<typename> struct result;
template<typename F, typename L, typename R>
struct result<F(L,R)>
{
typedef typename binary_operator<
L,
Op,
R
Quote:
::result_type type;
};



template struct result<F(T)>
{
typedef typename unary_operator<
Op,
T
Quote:
::result_type type;
};


template typename result<
operator_
Quote:
::type
operator()(L const& l, R const & r)

{
return binary_operator<L,Op,R>()(l,r);
}

template<typename L, typename R>
static
typename result<
operator_
Quote:
::type apply( L const& l,R const& r)
{

return binary_operator<L,Op,R>::apply(l, r);
}

template<typename T>
typename result<
operator_
Quote:
::type
operator()(const T & t)

{
return unary_operator<Op,T>()(t);
}

template<typename T>
static
typename result<
operator_
Quote:
::type apply(const T& t)
{

return unary_operator<Op,T>::apply(t);
}
};

regards
Andy Little

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language, library and standards All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.