Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

do_ leads to incosistency #89

Open
xR3b0rn opened this issue Dec 15, 2019 · 1 comment
Open

do_ leads to incosistency #89

xR3b0rn opened this issue Dec 15, 2019 · 1 comment

Comments

@xR3b0rn
Copy link

xR3b0rn commented Dec 15, 2019

Any unary lazy statement in boost::phoenix can be used like:

template <class I, class F>
void call_lzay_func(const I& i, const F& f)
{
    std::vector<int> vec;
    f[push_back(ref(vec), i)]();
}
int i;
f(ref(i), for_(ref(i) = 0, ref(i) < 5, ref(i)++));

The only exception is the do_ statement.

When I have a function taking a unary boost::phonenix lazy statement (like you can see in the example), I have to make a falling distinctive to handle the do_ specially.

I can't see any benefit in this. In which this simply change would solve the problem, without changing the semantic:

do_
[
    cout << arg1 << ", "
]
.while_(arg1--),

to

do_(arg1--)
[
    cout << arg1 << ", "
]

Isn't the current implementation incosistent in the manner of my example?

@xR3b0rn
Copy link
Author

xR3b0rn commented Dec 15, 2019

A quick fix:

#pragma once

#include <boost/phoenix/core/limits.hpp>
#include <boost/phoenix/core/call.hpp>
#include <boost/phoenix/core/expression.hpp>
#include <boost/phoenix/core/meta_grammar.hpp>

BOOST_PHOENIX_DEFINE_EXPRESSION(
    (boost)(phoenix)(do__)
  , (meta_grammar) // Cond
    (meta_grammar) // Do
)

namespace boost { namespace phoenix
{
    struct do__eval
    {
        typedef void result_type;
        template <typename Cond, typename Do, typename Context>
        result_type operator()(Cond const& cond, Do const& do_it, Context const & ctx) const
        {
            do
            {
                boost::phoenix::eval(do_it, ctx);
            } while (boost::phoenix::eval(cond, ctx));
        }
    };
    
    template <typename Dummy>
    struct default_actions::when<rule::do__, Dummy>
        : call<do__eval, Dummy>
    {};

    template <typename Cond>
    struct do__gen
    {
        do__gen(Cond const& cond_)
			: cond(cond_)
		{}

        template <typename Do>
        typename expression::do__<Cond, Do>::type const operator[](Do const& do_it) const
        {
            return expression::do__<Cond, Do>::make(cond, do_it);
        }

        const Cond& cond;
    };

    template <typename Cond>
    inline const do__gen<Cond> do__(Cond const& cond)
    {
        return do__gen<Cond>(cond);
    }
}}

This code is introducing a new statment: do__

The syntax for the statement is the same as for while_ but the behaviour is like the behaviour of a normal do.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant