Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8756737
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 13, 20262026-06-13T14:08:39+00:00 2026-06-13T14:08:39+00:00

I’m experimenting with Proto to build a DSEL that operates on geometric vectors. I’m

  • 0

I’m experimenting with Proto to build a DSEL that operates on geometric vectors. I’m trying to write a transform that would take an assign expression and unroll it component wise. For instance, I want to replace

p = q + r;

by

p[0] = q[0] + r[0],
p[1] = q[1] + r[1],
...,
p[N] = q[N] + r[N],
p;

So far I have been able to mostly make it work by making a transform template unroll_vector_expr that recursively unrolls the expression for each vector component, in conjunction with a distribute_subscript transform.

I don’t seem to understand whats the rationale for the ‘parameters’ used with boost::result_of and result_of::make_expr. The documentation, examples and internal code seem to mix Expr, impl::expr and impl::expr_param. I’m not sure what should I be using and when so that the result_type matches the actual result type. Currently I made it work by trial an error, by examining the error messages and fixing the const and & discrepancies. However, as soon as I deep copy the expression the terminals are no longer hold by reference and my code fails.

struct distribute_subscript
  : or_<
        scalar_grammar
      , when<
            vector_literal
          , _make_subscript( _, _state )
        >
      , plus< distribute_subscript, distribute_subscript >
      , minus< distribute_subscript, distribute_subscript >
      , multiplies< distribute_subscript, distribute_subscript >
      , divides< distribute_subscript, distribute_subscript >
      , assign< distribute_subscript, distribute_subscript >
    >
{};

template< std::size_t I, std::size_t N >
struct unroll_vector_expr_c;

template< std::size_t I, std::size_t N >
struct unroll_vector_expr_c
  : transform< unroll_vector_expr_c< I, N > >
{
    template< typename Expr, typename State, typename Data >
    struct impl
      : transform_impl< Expr, State, Data >
    {
        typedef
            typename result_of::make_expr<
                tag::comma
              , typename boost::result_of<
                    distribute_subscript(
                        Expr
                      , typename result_of::make_expr<
                            tag::terminal
                          , boost::mpl::size_t< I - 1 >
                        >::type
                    )
                >::type
              , typename boost::result_of<
                    unroll_vector_expr_c< I + 1, N >(
                        Expr
                    )
                >::type
            >::type
            result_type;

        result_type operator ()(
            typename impl::expr_param expr
          , typename impl::state_param state
          , typename impl::data_param data
        ) const
        {
            return
                make_expr< tag::comma >(
                    distribute_subscript()(
                        expr
                      , make_expr< tag::terminal >( 
                            boost::mpl::size_t< I - 1 >()
                        )
                    )
                  , unroll_vector_expr_c< I + 1, N >() (
                        expr
                    )
                );
        }
    };
};

template< std::size_t N >
struct unroll_vector_expr_c< N, N >
  : transform< unroll_vector_expr_c< N, N > >
{
    template< typename Expr, typename State, typename Data >
    struct impl
      : transform_impl< Expr, State, Data >
    {
        typedef
            typename boost::result_of<
                distribute_subscript(
                    Expr
                  , typename result_of::make_expr<
                        tag::terminal
                      , boost::mpl::size_t< N - 1 >
                    >::type
                )
            >::type
            result_type;

        result_type operator ()(
            typename impl::expr_param expr
          , typename impl::state_param state
          , typename impl::data_param data
        ) const
        {
            return
                distribute_subscript()(
                    expr
                  , make_expr< tag::terminal >( 
                        boost::mpl::size_t< N - 1 >()
                    )
                );
        }
    };
};

struct unroll_vector_expr
  : transform< unroll_vector_expr >
{
    template< typename Expr, typename State, typename Data >
    struct impl
      : transform_impl< Expr, State, Data >
    {
        typedef
            typename dimension<
                typename boost::remove_reference<
                    typename boost::result_of<
                        _value( State )
                    >::type
                >::type
            >::type
            dimension;

        typedef
            typename result_of::make_expr<
                tag::comma
              , typename boost::result_of<
                    unroll_vector_expr_c< 1, dimension::value >(
                        Expr
                    )
                >::type
              , State
            >::type
            result_type;

        result_type operator ()(
            typename impl::expr_param expr
          , typename impl::state_param state
          , typename impl::data_param data
        ) const
        {
            return
                make_expr< tag::comma >(
                    unroll_vector_expr_c< 1, dimension::value >()(
                        expr
                    )
                  , boost::ref( state )
                );
        }
    };
};

How should I write my transform so that the result_type matches the result from operator (), and works for terminals both hold by value and by reference?

Update: Code updated after Eric‘s answer. The only remaining mismatch between result_type and make_expr is for the first instantiation of unroll_vector_expr_c, where the terminal< mpl::size_t< 0 > >::type is held by const reference instead of by value. Curiously enough, subsequent instantiations of the same template with higher indices do not result in this issue.

Update: I managed to get the code to fully work, after modifying the distribue_subscript transform to force to take the subscript index by value:

struct distribute_subscript
  : or_<
        scalar_grammar
      , when<
            vector_literal
          , _make_subscript( _, _byval( _state ) ) // <-- HERE
        >
      , plus< distribute_subscript, distribute_subscript >
      , minus< distribute_subscript, distribute_subscript >
      , multiplies< distribute_subscript, distribute_subscript >
      , divides< distribute_subscript, distribute_subscript >
      , assign< distribute_subscript, distribute_subscript >
    >
{};
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-13T14:08:40+00:00Added an answer on June 13, 2026 at 2:08 pm

    A quick answer for now. I’ll try to look more closely at your transform tomorrow.

    The meaning of impl::expr and impl::expr_param can be understood by looking at documentation for transform_impl. In short, use impl::expr_param in the signature of your transform’s operator(), since it adds a const & to ensure that expressions don’t get copied when passed to your function. Use Expr in your type computations, like in boost::result_of. impl::expr isn’t useful for much and can be ignored.

    As for deep_copy always forcing your terminals to be held by value, that’s pretty much what deep_copy is for. But maybe you mean something else, since I don’t see deep_copy in your code anywhere.

    A word about make_expr: it forces you to think very carefully about which nodes should be stored by reference and which by value. In the type computation (result_of::make_expr), reference types are things that should be held by reference, but in the actual function call (proto::make_expr), you must wrap things with boost::ref if you want then held by reference. This is weird. Check the user docs for make_expr.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm parsing an RSS feed that has an &#8217; in it. SimpleXML turns this
I'm trying to create an if statement in PHP that prevents a single post
link Im having trouble converting the html entites into html characters, (&# 8217;) i
That's pretty much it. I'm using Nokogiri to scrape a web page what has
I am trying to understand how to use SyndicationItem to display feed which is
Basically, what I'm trying to create is a page of div tags, each has
I have a string like this: La Torre Eiffel paragonata all&#8217;Everest What PHP function
I've got a string that has curly quotes in it. I'd like to replace
I have a French site that I want to parse, but am running into
I am doing a simple coin flipping experiment for class that involves flipping a

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.