Boost logo

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