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

  • Home
  • SEARCH
  • 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 8438609
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 10, 20262026-06-10T07:45:46+00:00 2026-06-10T07:45:46+00:00

I was playing with Boost.Proto, mostly for fun and to see if in future

  • 0

I was playing with Boost.Proto, mostly for fun and to see if in future I could make some use of it in my own projects. That said,
as probably most beginners of this library, i’ve played with a modified version of the ‘lazy vector’ example, but using transforms instead of contexts to perform the evaluation. The vector is defined as follows (ok, i know, ‘vector’ is not a good name for something defined at the global namespace scope…)

template <std::size_t D, class T>
class vector { 
    T data_[D];
    enum { dimension = D };
    // Constructors, destructors...
};

// expression wrapper
template <class> class vector_expr;

it is templated on the dimension and the data type, kind of boost::array (i did not use that since i’d like to overload operator= to accept expression trees, as usually done in this sort of things). I defined scalars using code from proto’s manual

// scalar = everything convertible to double
struct scalar_terminal :
    proto::terminal<proto::convertible_to <double> >
{};

// vector = everything for which the is_vector returns true_
template <class T> struct is_vector : mpl::false_ {};
template <std::size_t D, class T> struct is_vector <vector <D, T> > : mpl::true_ {};

struct vector_terminal :
    proto::and_ <
       proto::terminal<_>
     , proto::if_<is_vector<proto::_value>()>
  >
{};

// domain   
struct vector_domain
    : proto::domain <proto::generator <vector_expr> >
{};

// expression wrapper
template <class Expr>
struct vector_expr : proto::extends <Expr, vector_expr <Expr>, vector_domain>
{
    typedef proto::extends <Expr, vector_expr <Expr>, vector_domain> base_type;

    // Construct from expression (enough to compile)
    vector_expr (Expr const &e) : base_type (e) {}
};

// Bring in operators
BOOST_PROTO_DEFINE_OPERATORS(is_vector, vector_domain)

Now, the first thing i wanted to do is: check if all vector terminals in an expression have the same
dimension D. I ended up with the following working code

// a meta-function that returns the vector dimension
template <class T>
struct vector_dim
{
    typedef mpl::int_ <T::dimension> type;
};

// a meta-function that combines dimensions from subtrees. int<-1> means
// that sub-trees store vectors of differing static dimension. No good.
template <class D1, class D2>
struct dim_combine
{
   typedef mpl::int_ < -1 > type;
};

// ok, dimensions are the same, propagate up the value
template <class D>
struct dim_combine <D, D>
{
   typedef D type;
};

// 0 is used to mark scalars. It is ok to mix vectors and scalars
// but propagate up the vector dimension only. This is for vector
// on the left and scalar on the right.
template <class D>
struct dim_combine <D, mpl::int_ <0> >
{
   typedef D type;
};

// this is for scalar on the left, vector to the right of some 
// binary operator.
template <class D>
struct dim_combine <mpl::int_ <0>, D>
{
   typedef D type;
};

// need this too to avoid ambiguity between the two specializations
// above when D is int_ <0>. Even if this combination should never
// happen
template <>
struct dim_combine <mpl::int_ <0>, mpl::int_<0> >
{
   typedef mpl::int_<0> type;
};


// A transform that check that all arrays have the same dimension
struct vec_dim_check
    : proto::or_ <
        proto::when <
            vector_terminal
          , vector_dim<proto::_value>()
        >
      , proto::when <
            scalar_terminal
          , boost::mpl::int_<0>()
        >
      , proto::when <
            proto::nary_expr<_, proto::vararg<_> >
          , proto::fold<_, boost::mpl::int_<0>(), dim_combine<vec_dim_check, proto::_state>()>
        >
    >
{};

template <class E>
void check_dim (E const&)
{
    typedef typename boost::result_of<vec_dim_check(E)>::type type;
    BOOST_ASSERT(type::value == 3);
}

int main (int, char**)
{
    vector <3,double> a,b,c;
    check_dim (2*a+b/c);
    return 0;
}

The question is: since the dimension of the arrays is already encoded in the expression, then it should
be possible to detect invalid combination already at compile time. It should be even possible to avoid
creating the tree in the first place. How is this achieved ?

Thanks in advance, best regards

  • 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-10T07:45:47+00:00Added an answer on June 10, 2026 at 7:45 am

    Very nice. Now you need to define a grammar that only accepts valid vector expressions something like this:

    struct vector_grammar_untyped
      : proto::or_<
            scalar_terminal,
            vector_terminal,
            proto::nary_expr<proto::_, proto::vararg<vector_grammar_untyped> >
        >
    {};
    
    struct vector_grammar
      : proto::and_<
            vector_grammar_untyped,
            proto::if_<mpl::not_equal_to< mpl::int_<-1>, vec_dim_check >()>
        >
    {};
    

    Then, you change your definition of vector_domain as follows:

    struct vector_domain
        : proto::domain <proto::generator <vector_expr>, vector_grammar >
    {};
    

    That should keep you from creating expressions that don’t pass your custom type-checking. The second template parameter to proto::domain is the grammar to which all expressions in that domain must conform.

    Disclaimer: The above code is untested, but it should get you moving in the right direction.

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

Sidebar

Related Questions

I've been playing around with some Boost components, and the only one I see
So, I've been playing around with the Boost asio functions and sockets (specifically the
Playing around with Python - tkInter - Entry widget - when I use validatecommand
Playing around with MongoDB and NoRM in .NET. Thing that confused me - there
I've been playing around with boost threads today as a learning exercise, and I've
I have been playing with D3.js and I am trying to make a Streaming
Playing around with Flask and just wanted to print out some data as JSON
Playing around with Google Maps these days, with some directions. I have a map
playing around with a property file i figured that there seems to be a
Playing around with shapeless natural numbers in excitement, I wonder what could be the

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.