|
Boost Users : |
From: Zeljko Vrba (zvrba_at_[hidden])
Date: 2005-07-11 04:38:05
Hi!
I'm trying to create a lisp-like 'map' functor. however, gcc complains
with (..follows). It seems that somehow it has a wrong idea of the
return value of the functor return value. The complete code (the header
and the test program) are in the attachment.
stage.h: In member function `typename phoenix::actor_result<map_c<ProviderT,
OperationT>, TupleT>::type map_c<ProviderT, OperationT>::eval(const
TupleT&)
const [with TupleT = phoenix::tuple<phoenix::nil_t, phoenix::nil_t,
phoenix::nil_t, phoenix::nil_t>, ProviderT =
phoenix::actor<phoenix::composite<typed_binary_istream_f<unsigned int>,
phoenix::nil_t, phoenix::nil_t, phoenix::nil_t, phoenix::nil_t> >,
OperationT = phoenix::actor<phoenix::composite<phoenix::times_op,
phoenix::actor<phoenix::composite<phoenix::dereference_op,
phoenix::actor<phoenix::argument<0> >, phoenix::nil_t, phoenix::nil_t,
phoenix::nil_t> >, phoenix::actor<phoenix::value<int> >, phoenix::nil_t,
phoenix::nil_t> >]':
/usr/pkg/include/boost/spirit/phoenix/actor.hpp:354: instantiated from
`typename phoenix::actor_result<BaseT, phoenix::tuple<phoenix::nil_t,
phoenix::nil_t, phoenix::nil_t, phoenix::nil_t>
>::type phoenix::actor<BaseT>::operator()() const [with BaseT =
map_c<phoenix::actor<phoenix::composite<typed_binary_istream_f<unsigned
int>, phoenix::nil_t, phoenix::nil_t, phoenix::nil_t,
phoenix::nil_t> >,
phoenix::actor<phoenix::composite<phoenix::times_op,
phoenix::actor<phoenix::composite<phoenix::dereference_op,
phoenix::actor<phoenix::argument<0> >, phoenix::nil_t, pho
enix::nil_t, phoenix::nil_t> >, phoenix::actor<phoenix::value<int> >,
phoenix::nil_t, phoenix::nil_t> > >]'
stage_test04.cc:34: instantiated from here
stage.h:172: error: conversion from `const int' to non-scalar type `const
phoenix::nil_t' requested
#ifndef STAGE_H__
#define STAGE_H__
#include <utility>
#include <istream>
#include <boost/spirit/phoenix/functions.hpp>
#include <boost/spirit/phoenix/composite.hpp>
/**
* @file
* Stage fundamentals. Each stage returns a POINTER to value. 0 means that
* the stage is exhausted, and 0 will be returned each time afterwards.
*
* Some conventions: _p are primitives, _c are composites, _f functions.
*/
/*****************************************************************************
* Typed binary stream reads items from an istream and returns a pointer to
* the newly read item. When there are no more items to read, returns 0.
****************************************************************************/
template<class ItemT>
struct typed_binary_istream_f {
typedef ItemT *result_type;
ItemT *operator()() const {
return is.read((char*)&storage, sizeof(storage)) ?
const_cast<ItemT*>(&storage) : 0;
}
typed_binary_istream_f(std::istream &is_) : is(is_) { }
std::istream &is;
ItemT storage;
};
template<class ItemT>
phoenix::function<typed_binary_istream_f<ItemT> >
typed_binary_istream(std::istream &is)
{
return typed_binary_istream_f<ItemT>(is);
}
/*****************************************************************************
* Calls the provider repeatedly until it returns 0. Operation is executed on
* all elements returned by the provider.
****************************************************************************/
template<typename ProviderT, typename OperationT>
struct until_eof_c {
typedef until_eof_c<ProviderT, OperationT> self_t;
template<typename TupleT>
struct result { typedef void type; };
until_eof_c(ProviderT const &provider_, OperationT const &op_) :
provider(provider_), operation(op_) { }
template<typename TupleT>
void eval(TupleT const &args) const;
ProviderT provider;
OperationT operation;
};
template<typename ProviderT, typename OperationT>
template<typename TupleT>
void until_eof_c<ProviderT, OperationT>::eval(TupleT const &args) const
{
typename phoenix::actor_result<ProviderT, TupleT>::type p;
while((p = provider()))
operation(p);
}
template<typename ProviderT, typename OperationT>
phoenix::actor<until_eof_c<
typename phoenix::as_actor<ProviderT>::type,
typename phoenix::as_actor<OperationT>::type> >
until_eof(ProviderT const &provider, OperationT const &operation)
{
typedef until_eof_c<
typename phoenix::as_actor<ProviderT>::type,
typename phoenix::as_actor<OperationT>::type> result;
return result(
phoenix::as_actor<ProviderT>::convert(provider),
phoenix::as_actor<OperationT>::convert(operation));
}
/*****************************************************************************
* Returns only elements that match some predicate.
****************************************************************************/
template<typename ProviderT, typename PredicateT>
struct filter_c {
typedef filter_c<ProviderT, PredicateT> self_t;
template<typename TupleT>
struct result {
typedef typename
phoenix::actor_result<ProviderT, TupleT>::type type;
};
filter_c(ProviderT const &provider_, PredicateT const &p_) :
provider(provider_), predicate(p_) { }
template<typename TupleT>
typename phoenix::actor_result<self_t, TupleT>::type
eval(TupleT const &args) const;
ProviderT provider;
PredicateT predicate;
};
template<typename ProviderT, typename PredicateT>
template<typename TupleT>
typename phoenix::actor_result<
typename filter_c<ProviderT, PredicateT>::self_t, TupleT>::type
filter_c<ProviderT, PredicateT>::eval(TupleT const &args) const
{
typename phoenix::actor_result<ProviderT, TupleT>::type p;
while((p = provider()))
if(predicate(p)) return p;
return 0;
}
template<typename ProviderT, typename PredicateT>
phoenix::actor<filter_c<
typename phoenix::as_actor<ProviderT>::type,
typename phoenix::as_actor<PredicateT>::type> >
filter(ProviderT const &provider, PredicateT const &operation)
{
typedef filter_c<
typename phoenix::as_actor<ProviderT>::type,
typename phoenix::as_actor<PredicateT>::type> result;
return result(
phoenix::as_actor<ProviderT>::convert(provider),
phoenix::as_actor<PredicateT>::convert(operation));
}
/*****************************************************************************
* Apply operation to each element of the provider and return the transformed
* sequence. This is called 'map' in LISPs.
****************************************************************************/
template<typename ProviderT, typename OperationT>
struct map_c {
typedef map_c<ProviderT, OperationT> self_t;
template<typename TupleT>
struct result {
typedef typename
phoenix::actor_result<OperationT, TupleT>::type type;
};
map_c(ProviderT const &provider_, OperationT const &op_) :
provider(provider_), operation(op_) { }
template<typename TupleT>
typename phoenix::actor_result<self_t, TupleT>::type
eval(TupleT const &args) const;
ProviderT provider;
OperationT operation;
};
template<typename ProviderT, typename OperationT>
template<typename TupleT>
typename phoenix::actor_result<
typename map_c<ProviderT, OperationT>::self_t, TupleT>::type
map_c<ProviderT, OperationT>::eval(TupleT const &args) const
{
typename phoenix::actor_result<ProviderT, TupleT>::type p;
p = provider();
// while((p = provider()))
// if(operation(p)) return p;
return operation(p);
}
template<typename ProviderT, typename OperationT>
phoenix::actor<map_c<
typename phoenix::as_actor<ProviderT>::type,
typename phoenix::as_actor<OperationT>::type> >
map(ProviderT const &provider, OperationT const &operation)
{
typedef map_c<
typename phoenix::as_actor<ProviderT>::type,
typename phoenix::as_actor<OperationT>::type> result;
return result(
phoenix::as_actor<ProviderT>::convert(provider),
phoenix::as_actor<OperationT>::convert(operation));
}
#ifdef STAGE_INSTANTIATE__
#endif
#endif // STAGE_H__
#include <iostream>
#include <fstream>
#include <boost/spirit/phoenix/primitives.hpp>
#include <boost/spirit/phoenix/operators.hpp>
#define STAGE_INSTANTIATE__
#include "stage.h"
using namespace std;
using namespace phoenix;
struct print_f {
template<typename ItemT>
struct result { typedef bool type; };
template<typename ItemT>
bool operator()(ItemT const &item) const {
cout << item << endl;
return item;
}
};
static function<print_f> print;
int main(int argc, char **argv)
{
unsigned int *item;
fstream f("test1.bin");
if(!f) {
cerr << "can't open test1.bin\n";
return 1;
}
map(typed_binary_istream<unsigned int>(f)(), *arg1 * 2) ();
return 0;
}
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net