Re: [proto] Using a derived class as terminals in Boost.proto

2016-04-14 Thread Frank Winter



On 04/14/2016 10:10 AM, Mathias Gaunard wrote:

On 14 April 2016 at 14:43, Frank Winter <fwin...@jlab.org
<mailto:fwin...@jlab.org>> wrote:

Hi all!

Suppose you'd want to implement a simple EDSL (Embedded Domain
Specific Language) with Boost.proto with the following requirements:

 Custom class 'Vector' as terminal
 Classes derived from 'Vector' are working terminals too, e.g.
Vector10

[...]

template
struct IsVector
   : mpl::false_
{};


template<>
struct IsVector< Vector >
   : mpl::true_
{};


Surely this should be true for all types derived from Vector.

template
struct IsVector
   : mpl::false_
{};

template
struct IsVector<T, typanem enable_if< is_base_of<Vector, T> >::type>
   : mpl::true_
{};




I had tried this


template<>
struct IsVector< Vector10 >
  : mpl::true_
{};


before. Same error message. Now I tried the base_of implementation


template
struct IsVector
  : mpl::false_
{};

template
struct IsVectorT>::value >::type>

  : mpl::true_
{};


and still, I get basically the same error message:

/home/fwinter/src/boost_1_60_0/boost/proto/context/default.hpp:121:41: 
error: no match for ‘operator+’ (operand types are ‘Vector10’ and 
‘Vector10’)

 BOOST_PROTO_BINARY_DEFAULT_EVAL(+, proto::tag::plus, make, make)


It's weird since the operator+ should be there for Vector, and since I 
am importing the namespace VectorOps, it should work for derived 
classes. I don't see why it's not working.


Thanks,
Frank




___
proto mailing list
proto@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/proto



___
proto mailing list
proto@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/proto


[proto] Using a derived class as terminals in Boost.proto

2016-04-14 Thread Frank Winter

Hi all!

Suppose you'd want to implement a simple EDSL (Embedded Domain Specific 
Language) with Boost.proto with the following requirements:


Custom class 'Vector' as terminal
Classes derived from 'Vector' are working terminals too, e.g. Vector10

Reading the manual of Boost.proto it seems the closest related example 
to this would be the 'Vector: Adapting a Non-Proto Terminal Type' example.


Modifications I did to that example:

Added 'Vector' class
Protofied Vector instead of std::vector

Here the code (compiles):


// 

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
namespace mpl = boost::mpl;
namespace proto = boost::proto;
using proto::_;

class Vector;

template
struct VectorExpr;

struct VectorSubscriptCtx
{
VectorSubscriptCtx(std::size_t i)
  : i_(i)
{}

template
struct eval
  : proto::default_eval
{};

template
struct eval<
Expr
  , typename boost::enable_if<
proto::matches >
>::type
>
{
typedef typename 
proto::result_of::value::type::value_type result_type;


result_type operator ()(Expr , VectorSubscriptCtx const 
) const

{
return proto::value(expr)[ctx.i_];
}
};

std::size_t i_;
};




struct VectorGrammar : proto::or_<
proto::terminal< proto::_ >,
proto::plus< VectorGrammar, VectorGrammar>,
proto::minus< VectorGrammar, VectorGrammar>
> {};

struct VectorDomain
  : proto::domain
{};



template
struct VectorExpr
  : proto::extends
{
explicit VectorExpr(Expr const )
  : proto::extends(expr)
{}

typename proto::result_of::evalconst>::type

operator []( std::size_t i ) const
{
VectorSubscriptCtx const ctx(i);
return proto::eval(*this, ctx);
}
};




class Vector {
private:
  int sz;
  double* data;

public:
  typedef double value_type;

  explicit Vector(int sz_ = 1, double iniVal = 0.0) :
sz( sz_), data( new double[sz] ) {
for (int i = 0; i < sz; i++) data[i] = iniVal;
  }
  Vector(const Vector& vec) :
sz( vec.sz), data( new double[sz] ) {
for (int i = 0; i < sz; i++) data[i] = vec.data[i];
  }

  size_t size() const {return sz; }

  ~Vector() {
delete [] data;
  }

  double& operator[](int i) { return data[i]; }
  const double& operator[](int i) const { return data[i]; }
};



class Vector10: public Vector
{
public:
  Vector10() : Vector(10,0.0) {}
};




template
struct IsVector
  : mpl::false_
{};


template<>
struct IsVector< Vector >
  : mpl::true_
{};



namespace VectorOps
{
BOOST_PROTO_DEFINE_OPERATORS(IsVector, VectorDomain)

typedef VectorSubscriptCtx const CVectorSubscriptCtx;

template
Vector (Vector , Expr const )
{
for(std::size_t i = 0; i < arr.size(); ++i)
{
arr[i] = proto::as_expr(expr)[i];
}
return arr;
}
}



int main()
{
using namespace VectorOps;

Vector a,b,c,d;

VectorOps::assign(d, a + b );
}


// 


There's already the derived class Vector10 defined. Now - using that one 
instead of Vector


int main()
{
using namespace VectorOps;

Vector10 a,b,c,d;

VectorOps::assign(d, a + b );
}


I believe that the operators for Vector are correctly defined in the 
namespace VectorOps but the ADL doesn't kick in for the derived class.


Any idea how this can be fixed?

Thanks,
Frank




___
proto mailing list
proto@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/proto