 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
kwikius Guest
|
Posted: Fri Jul 09, 2004 5:45 am Post subject: common result_of for operations |
|
|
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 |
|
 |
|
|
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
|
|