
::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,
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> 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; }