Re: mapcar contest
On 11/ 7/10 11:51 AM, jacob navia wrote:
Hi
I am writing a container library in C. I have developed iterators, and
generic containers, and to test my library I wrote the lisp function
"mapcar".
Mapcar takes a list and builds a list containing the result of a monadic
function applied to each element of the input list.
For instance
(mapcar #'abs (1 -2 3 -4 5 -6 7))
will produce
(1 2 3 4 5 6 7)
i.e. the function 'abs' will be applied to each element.
Within my software, mapcar looks like this:
int mapcar(SequentialContainer *src, /* The source container */
void *(*fn)(void *),/* Function to call with each element */
SequentialContainer *result) /* The resulting container */
<snip because Thunderbird munts code!>
"SequentialContainer" is an abstract class that includes lists, arrays,
stringcollections, and all containers that have a natural sequence
(index) that follows the natural integers. The result of "mapcar" then,
will be of the same actual type that the "result" container passed to
mapcar.
Now (at last) my question:
What would be the corresponding C++ code?
The idiomatic solution is probably to use std::transform:
int main()
{
int data[] = {1, -2, 3, -4, 5, -6, 7};
std::vector<int> vi(data, data+sizeof(data)/sizeof(int));
std::list<int> li;
std::list<int>::iterator it(li.begin());
std::insert_iterator< std::list<int> > insert(li,it);
std::transform( vi.begin(), vi.end(), insert, abs );
return 0;
}
What would be the best way of implementing it?
If you don't want to use iterators and you want to use generic in and
out containers, something like:
template <typename T,
template <typename X,typename A=std::allocator<X> > class In,
template <typename X,typename A=std::allocator<X> > class Out,
typename Op>
void mapcar( const In<T>& in, Out<T>& out, Op op )
{
typename Out<T>::iterator it(out.begin());
std::insert_iterator< Out<T> > insert(out,it);
std::transform( in.begin(), in.end(), insert, abs );
}
Which would be called as
std::vector<int> vi;
std::list<int> li;
mapcar( vi, li, abs );
--
Ian Collins