C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

expression templates challenge: *container of various types*

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
archondas
Guest





PostPosted: Thu Jan 06, 2005 7:06 pm    Post subject: expression templates challenge: *container of various types* Reply with quote



Dear C++ experts,
I am writting something which uses a lot
of expression templates stuff. I would like
to avoid inheritance because I am a little bit
frightened with virtual functions, even with just
virtual destructors. Recently I had posted a bug
in g++-3.4.3 where if you declare a destructor
virtual (there are no virtual functions in that
code just the destructor) the performance drops
from 3 seconds to 10 seconds. Intel's icc compiler
has no problem with that thing! So forgetting about
inheritance is there any other more sophisticated
way to do the following?

*** Container(vector or matrix) with different types ***

What I have is the following:
An expression which combines several types for instance:

typeA A,v;
typeB B;
typeC C;

typeof( A*v + fun1(A)*fun1(v) + B*fun2(v) + fun3(C)*fun1(v) )
expression = A*v + fun1(A)*fun1(v) + B*fun2(v) + fun3(C)*fun1(v);

// That expression combines 3 different types. What I need is a way
// such that expression automatically understands the three different
// types and stores both the types and the objects in a class or
// some kind of container from which they also can be indexed.

Quote:
typeA A|
mycontainer = |typeB B|
typeC C|

a possible aproach is this:

template<typename A, typename B, typename C>
class TypeContainer
{
private:
const A& a_;
const B& b_;
const C& c_;

public:
TypeContainer(const A& a, const B& b, const C& c) : a_(a), b_(b),
c_(c)
{}

// the problem is that I want an indexing mechanism such that
// I can write the following

theReturnTypeIsAProblem& operator[](uint i)
{
if(i == 0)
{
return c_;
}

if (i == 1)
{
return b_;
}

if (i == 2)
{
return c_;
}
}

// which is not allowed

};

If the extension Bjarne Stourstroup has suggested for the "auto"
keyword is implemented, then I easily solve my problem declaring
the return type of the operator auto.

But what can I do at the moment?

The reason I need such a type container is because I want to pass
the expression above in another class which needs to know how many
different types exists in the expression in order to do its job
properly. Its job is to extract some information which is different
for those different types and combine them properly in order to built
some other structure!

1: With all that in mind can someone give me a hint
how to implement such a type container?

2: Suppose the above is feasible. How can we program the
expression class above such that it can automatically,
while assembling the expression, create the container
we want???

Thank you all for your help in advance!
Best Wishes!
D.K.




[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Stefan Strasser
Guest





PostPosted: Sat Jan 08, 2005 2:25 am    Post subject: Re: expression templates challenge: *container of various ty Reply with quote



I don't understand what you're trying to do so I just comment this one:


archondas schrieb:
Quote:
theReturnTypeIsAProblem& operator[](uint i)
{
if(i == 0)
{
return c_;
}

if (i == 1)
{
return b_;
}

if (i == 2)
{
return c_;
}
}

// which is not allowed

};

If the extension Bjarne Stourstroup has suggested for the "auto"
keyword is implemented, then I easily solve my problem declaring
the return type of the operator auto.


no, you'll never get a function whose return type depends on a runtime
variable. the "auto" proposal just makes the compiler figure out the type.
e.g. A a; auto a2=a; makes a2 another A.
but you can't assign a completely unrelated type to a2 in the next step,
like you're doing with return.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
jarl
Guest





PostPosted: Sat Jan 08, 2005 5:59 am    Post subject: Re: expression templates challenge: *container of various ty Reply with quote



Quote:
Dear C++ experts,
....can one ever be? Wink


...<snip>...

Well, I have a suggestion which might help you, but it's not perfect.
Essentially you introduce a proxy class and return that from your index
operator instead of the "raw" type. The proxy is invisible to the user
but handles the assignment and conversions to allow transparent use. A
simple version (which does not use type information) could be done like
this:

class TypeProxy
{
void* field_; //< could be "volatile void*" if you want to be
picky
public:
explicit TypeProxy(void* f) : field_(f) {}
TypeProxy( const TypeProxy& rhs ) : field_(rhs.field_) {}
TypeProxy& operator=(const TypeProxy& rhs)
{
field_ = rhs.field_;
return *this;
}
template F& operator=(const F& value)
{
return *reinterpret_cast<F*>(field_) = value;
}
template<typename F>
operator F() const
{
return *reinterpret_cast<F*>(field_);
}
};

Then your container index operator does this: (with a little rewrite,
your a's and c's were swapped)

TypeProxy operator[](uint i)
{
if(i == 0)
{
return TypeProxy(&a_);
}

if (i == 1)
{
return TypeProxy(&b_);
}

return TypeProxy(&c_);
}

This way you can access and mutate through your container:

TypeContainer<int,float,Foo> mycontainer(a,b,c);
mycontainer[0] = 42;
Foo tmp = mycontainer[2];
....

etc.

You can add type information and checking if you want to (the type
proxy could use this in debug build only if you worry about size).
-=jarl


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
David Abrahams
Guest





PostPosted: Sat Jan 08, 2005 10:52 pm    Post subject: Re: expression templates challenge: *container of various ty Reply with quote

archondas wrote:

Quote:
What I have is the following:


Quote:
// That expression combines 3 different types. What I need is a way
// such that expression automatically understands the three different
// types and stores both the types and the objects in a class or
// some kind of container from which they also can be indexed.

That's easy, provided you know the index as a compile-time constant.
Use boost::tuple<A,B,C> or if you feel like using the next-generation
tool, the tuples described at
http://www.boost.org/libs/spirit/fusion/readme.txt,
boost::fusion::tuple<A,B,C>. Fusion tuples are also valid MPL sequences.

You can then say:

get<N>(some_tuple)

and get the Nth element.

Quote:
a possible aproach is this:

template<typename A, typename B, typename C
class TypeContainer
{
private:
const A& a_;
const B& b_;
const C& c_;

public:
TypeContainer(const A& a, const B& b, const C& c) : a_(a), b_(b),
c_(c)
{}

// the problem is that I want an indexing mechanism such that
// I can write the following

theReturnTypeIsAProblem& operator[](uint i)

};

If the extension Bjarne Stourstroup has suggested for the "auto"
keyword is implemented, then I easily solve my problem declaring
the return type of the operator auto.

'Fraid not. The compiler would have the same problem that you would.
One possibility would be for it to use the type of

true ? a_ : true ? b_ : c_

as the return type, but that doesn't seem very popular in the committee,
and I'm guessing that for your particular A, B, and C, that expression
isn't valid anyway.

Your problem is that you're trying to index with a runtime value. If
you really need to be able to do that, you'll have to return some sort
of variant type, such as boost::any, or boost::variant don't want to use boost::any if you care about speed though. In any
case it's surely moot, because expression templates don't require the
use of variant types. I'm sure you can use compile-time indexing and
stick with tuples.

Quote:
But what can I do at the moment?

The reason I need such a type container is because I want to pass
the expression above in another class which needs to know how many
different types exists in the expression in order to do its job
properly.

Using fusion tuples, that's just:

mpl::size<
mpl::unique<
mpl::sort
Quote:
::type
::value

or

mpl::size<
mpl::copy<
some_tuple
, mpl::inserter< mpl::set<>, mpl::insert<_1, _2> >
Quote:
::type
::value

can't say which will be faster (at compile-time) for you.

Quote:
Its job is to extract some information which is different
for those different types and combine them properly in order to built
some other structure!

1: With all that in mind can someone give me a hint
how to implement such a type container?

My biggest hint is: don't do it yourself! Use ready-made off-the-shelf
boost components.

Quote:
2: Suppose the above is feasible. How can we program the
expression class above such that it can automatically,
while assembling the expression, create the container
we want???

I don't understand the question.

--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Graeme Prentice
Guest





PostPosted: Sat Jan 08, 2005 10:55 pm    Post subject: Re: expression templates challenge: *container of various ty Reply with quote




I'm reposting this because my other two posts didn't turn up - the
second of which had minor corrections to the code. However I've since
realised that the Typelist solution I'm suggesting here does form the
"type container" asked for but doesn't hold any of the "object
information" - I'm posting it anyway because it might give you some
ideas. The expression object you have does contain the objects you are
interested in and it *may* be possible to iterate through them - but
it's probably not easy. Also, detecting duplicate uses of the same
object probably makes it harder.



On 6 Jan 2005 14:06:24 -0500, archondas wrote:

Quote:
Dear C++ experts,
I am writting something which uses a lot
of expression templates stuff. I would like

[snip]

Quote:
What I have is the following:
An expression which combines several types for instance:

typeA A,v;
typeB B;
typeC C;

typeof( A*v + fun1(A)*fun1(v) + B*fun2(v) + fun3(C)*fun1(v) )
expression = A*v + fun1(A)*fun1(v) + B*fun2(v) + fun3(C)*fun1(v);

// That expression combines 3 different types. What I need is a way
// such that expression automatically understands the three different
// types and stores both the types and the objects in a class or
// some kind of container from which they also can be indexed.


[snip]

Quote:

// the problem is that I want an indexing mechanism such that

[snip]

Quote:

But what can I do at the moment?

The reason I need such a type container is because I want to pass
the expression above in another class which needs to know how many
different types exists in the expression in order to do its job
properly. Its job is to extract some information which is different
for those different types and combine them properly in order to built
some other structure!

1: With all that in mind can someone give me a hint
how to implement such a type container?

2: Suppose the above is feasible. How can we program the
expression class above such that it can automatically,
while assembling the expression, create the container
we want???


Surprisingly, I think this is possible using typelists - there's an
outline below. Typelist comes from Andreii Alexandrescu's Loki library
and are described in his book Modern C++ Design. A typelist is a chain
of types and the Loki library provides compile time mechanisms for
getting the length of a typelist, for extracting the type at a
particular index, for getting the index of a type, removing duplicates
from a typelist and appending to a typelist.

If you look at the return type of operator+ below, you'll see it returns
an expr_obj<> which incorporates both the type of the operation being
performed and a typelist of all the types so far. Hence for your final
"expression" object, you can enumerate it's types by using the second
type of expr_obj<t1,t2> i.e. here t2 has type Loki::Typelist and you
can get its length with
Loki::TL::Length<t2>

op_typelist_type::result is a Typelist regardless of the types of t1,t2
template parameters so for an operator+ that has arguments of e.g.
int,int, op_typelist_type<int,int>::result is a Typelist containing a
single type - int. - what I'm trying to say is that it works for both
expr_obj types and other types that don't already have a typelist
embedded in them. Note that the first argument for Append must be a
typelist.

This code is untested and I can't tell for sure if it will do what you
want. Good luck!

Graeme


#include "Typelist.h"
#include "TypeManip.h"
using namespace Loki;
using namespace Loki::TL;

template <typename t,typename tlist>
struct expr_obj
{
t obj;
typedef tlist expr_tlist;
typedef t expr_type;
};

template <typename t>
struct get_obj_typelist {
typedef Typelist<t,NullType> tlist;
};

template <typename t1,typename t2>
struct get_obj_typelist< expr_obj {
typedef t2 tlist;
};

template <typename t1, typename t2>
struct op_typelist_type
{
typedef
NoDuplicates<
Append<
typename get_obj_typelist typename get_obj_typelist<t2>::tlist > >
result;
};


template <typename t1, typename t2>
struct Add
{
};

template <typename t1, typename t2, typename t3, typename t4>
expr_obj< Add
operator+ ( expr_obj<t1,t2> const & x, expr_obj<t3,t4> const & y );


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
archondas
Guest





PostPosted: Sun Jan 09, 2005 10:06 am    Post subject: about assertions, #include <cassert> Reply with quote

Hi all once again!
This time with a newbie question!
Assertions is something I have not widely used.
I have seen that a lot of people do not think highly,
of
#include <cassert>
bla-bla-bla
assert(condition)
bla-bla-bla

some even characterize them as:
poor man assertions!

So which is the best way to code assertions?
Should we or shouldn't we use <cassert>?
Is there any better strategy?

Thanks in advance!
D.K.



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Graeme Prentice
Guest





PostPosted: Sun Jan 09, 2005 12:42 pm    Post subject: Re: expression templates challenge: *container of various ty Reply with quote


[note to moderator deleted --mod]
On 6 Jan 2005 14:06:24 -0500, archondas wrote:

Quote:
Dear C++ experts,
I am writting something which uses a lot
of expression templates stuff. I would like

[snip]

Quote:
What I have is the following:
An expression which combines several types for instance:

typeA A,v;
typeB B;
typeC C;

typeof( A*v + fun1(A)*fun1(v) + B*fun2(v) + fun3(C)*fun1(v) )
expression = A*v + fun1(A)*fun1(v) + B*fun2(v) + fun3(C)*fun1(v);

// That expression combines 3 different types. What I need is a way
// such that expression automatically understands the three different
// types and stores both the types and the objects in a class or
// some kind of container from which they also can be indexed.


[snip]

Quote:

// the problem is that I want an indexing mechanism such that

[snip]

Quote:

But what can I do at the moment?

The reason I need such a type container is because I want to pass
the expression above in another class which needs to know how many
different types exists in the expression in order to do its job
properly. Its job is to extract some information which is different
for those different types and combine them properly in order to built
some other structure!

1: With all that in mind can someone give me a hint
how to implement such a type container?

2: Suppose the above is feasible. How can we program the
expression class above such that it can automatically,
while assembling the expression, create the container
we want???


Surprisingly, I think this is possible using typelists - there's an
outline below. Typelist comes from Andreii Alexandrescu's Loki library
and are described in his book Modern C++ Design. A typelist is a chain
of types and the Loki library provides compile time mechanisms for
getting the length of a typelist, for extracting the type at a
particular index, for getting the index of a type, removing duplicates
from a typelist and appending to a typelist.

If you look at the return type of operator+ below, you'll see it returns
an expr_obj<> which incorporates both the type of the operation being
performed and a typelist of all the types so far. Hence for your final
"expression" object, you can enumerate it's types by using the second
type of expr_obj<t1,t2> i.e. here t2 has type Loki::Typelist and you
can get its length with
Loki::TL::Length<t2>

op_typelist_type::result is a Typelist regardless of the types of t1,t2
template parameters so for an operator+ that has arguments of e.g.
int,int, op_typelist_type<int,int>::result is a Typelist containing a
single type - int. - what I'm trying to say is that it works for both
expr_obj types and other types that don't already have a typelist
embedded in them. Note that the first argument for Append must be a
typelist.

This code is untested and I can't tell for sure if it will do what you
want. Good luck!

Graeme


#include "Typelist.h"
#include "TypeManip.h"
using namespace Loki;
using namespace Loki::TL;

template <typename t,typename tlist>
struct expr_obj
{
t obj;
typedef tlist expr_tlist;
typedef t expr_type;
};

template <typename t>
struct get_obj_typelist {
typedef Typelist<t,NullType> tlist;
};

template <typename t1,typename t2>
struct get_obj_typelist< expr_obj {
typedef t2 tlist;
};

template <typename t1, typename t2>
struct op_typelist_type
{
typedef
NoDuplicates<
Append<
typename get_obj_typelist typename get_obj_typelist<t2>::tlist > >
result;
};


template <typename t1, typename t2>
struct Add
{
};

template <typename t1, typename t2, typename t3, typename t4>
expr_obj< Add
operator+ ( expr_obj<t1,t2> const & x, expr_obj<t3,t4> const & y );


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Simon Perreault
Guest





PostPosted: Tue Jan 11, 2005 1:01 pm    Post subject: Re: about assertions, #include <cassert> Reply with quote

archondas wrote:
Quote:
So which is the best way to code assertions?
Should we or shouldn't we use <cassert>?
Is there any better strategy?

In my tight numerical code I use these assertions so that they go away when
compiling with NDEBUG. They are also part of the standard, which makes them
available everywhere. These two criterias are very important for me.

--
Simon Perreault <nomis80 (AT) nomis80 (DOT) org> -- http://nomis80.org

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
alnsn
Guest





PostPosted: Tue Jan 11, 2005 10:41 pm    Post subject: Re: expression templates challenge: *container of various ty Reply with quote

David Abrahams wrote:
Quote:
Using fusion tuples, that's just:

mpl::size
mpl::unique
mpl::sort<some_tuple>::type

::type
::value

Are you sure about this? mpl::sort expects a sequence of Integral
Constant types unless a predicate is explicitly given.

Quote:
or

mpl::size
mpl::copy
some_tuple
, mpl::inserter< mpl::set<>, mpl::insert<_1, _2

::type
::value

This one is fine as demonstrated in complete example:

#include #include <boost/mpl/set.hpp>
#include <boost/mpl/copy.hpp>
#include <boost/mpl/sort.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/insert.hpp>
#include <boost/mpl/inserter.hpp>

int main()
{
using namespace boost;

using mpl::_1;
using mpl::_2;

typedef mpl::vector<int,char,int,char> vec;

typedef mpl::copy< vec
, mpl::inserter
Quote:
::type r1;
// Doesn't work:

// typedef mpl::sort<vec>::type r2;
}

--
Alexander Nasonov


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Larry Evans
Guest





PostPosted: Wed Jan 12, 2005 8:56 pm    Post subject: Re: expression templates challenge: *container of various ty Reply with quote

On 01/08/2005 03:52 PM, David Abrahams wrote:
Quote:
archondas wrote:
[snip]
// That expression combines 3 different types. What I need is a way
// such that expression automatically understands the three different
// types and stores both the types and the objects in a class or
// some kind of container from which they also can be indexed.

[snip]
2: Suppose the above is feasible. How can we program the
expression class above such that it can automatically,
while assembling the expression, create the container
we want???


I don't understand the question.


Isn't this what Joel Guzman's grammar does as its assembling the
productions, each of which can be a different type? The example
code in:

http://article.gmane.org/gmane.comp.parsers.spirit.devel/2299

illustrates this, AFAICT. Certainly the typed of factor, term,
and expression are all different types; yet, he manages to store
them in a container (i.e. the grammar) and access the elements via
meaningful names ( i.e. factor, term, ...etc). I'd think it could
be adapted to access the elements via get<factor> or some other
"index" as the OP desires.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
David Abrahams
Guest





PostPosted: Wed Jan 12, 2005 9:06 pm    Post subject: Re: expression templates challenge: *container of various ty Reply with quote

alnsn wrote:
Quote:
David Abrahams wrote:
Using fusion tuples, that's just:

mpl::size
mpl::unique
mpl::sort<some_tuple>::type

::type
::value

Are you sure about this? mpl::sort expects a sequence of Integral
Constant types unless a predicate is explicitly given.

Oops, you're quite right. Serves me right for posting untested code.

Quote:
or

mpl::size
mpl::copy
some_tuple
, mpl::inserter< mpl::set<>, mpl::insert<_1, _2

::type
::value

This one is fine as demonstrated in complete example:

At least one of my answers is okay ;-)

--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
David Abrahams
Guest





PostPosted: Thu Jan 13, 2005 12:16 pm    Post subject: Re: expression templates challenge: *container of various ty Reply with quote

Larry Evans wrote:
Quote:
On 01/08/2005 03:52 PM, David Abrahams wrote:
archondas wrote:
[snip]
// That expression combines 3 different types. What I need is a way
// such that expression automatically understands the three different
// types and stores both the types and the objects in a class or
// some kind of container from which they also can be indexed.

[snip]
2: Suppose the above is feasible. How can we program the
expression class above such that it can automatically,
while assembling the expression, create the container
we want???


I don't understand the question.


Isn't this what Joel Guzman's grammar does as its assembling the
productions, each of which can be a different type?

Joel wasn't the first to do this, FWIW. It came from FC++ by Brian
McNamara and Yannis Smaragdakis.

Quote:
The example code in:

http://article.gmane.org/gmane.comp.parsers.spirit.devel/2299

illustrates this, AFAICT. Certainly the typed of factor, term,
and expression are all different types; yet, he manages to store
them in a container (i.e. the grammar) and access the elements via
meaningful names ( i.e. factor, term, ...etc). I'd think it could
be adapted to access the elements via get<factor> or some other
"index" as the OP desires.

I know how this works, but I fail to see any connection with the OP's
question #2.

--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
archondas
Guest





PostPosted: Sat Jan 15, 2005 4:10 am    Post subject: Re: expression templates challenge: *container of various ty Reply with quote

Dear David,
I am not quite sure how this piece of code you gave me
Quote:
mpl::size
mpl::copy
some_tuple
, mpl::inserter< mpl::set<>, mpl::insert<_1, _2

::type
::value

works and how it solves my problem!
Can you explain things a little bit please?

Thanks in advance!


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
David Abrahams
Guest





PostPosted: Sun Jan 16, 2005 5:03 am    Post subject: Re: expression templates challenge: *container of various ty Reply with quote

archondas wrote:
Quote:
Dear David,
I am not quite sure how this piece of code you gave me
mpl::size
mpl::copy
some_tuple
, mpl::inserter< mpl::set<>, mpl::insert<_1, _2

::type
::value

works and how it solves my problem!

Well, I'm not certain I really understand what your problem is, but you
said:

Quote:
The reason I need such a type container is because I want to pass
the expression above in another class which needs to know how many
different types exists in the expression in order to do its job
properly.

The expression above computes at compile-time the number of distinct
types contained in some_tuple, which appears to be what you're asking
for above. It does that by treating some_tuple as an MPL type sequence
(all fusion tuples are MPL type sequences), and inserting each of its
elements into a set of types, which starts out empty. That's what

mpl::copy<
some_tuple
, mpl::inserter<
mpl::set<> // begin with an empty set
, mpl::insert<_1,_2> // insert each element of some_tuple
Quote:

::type

does. You can learn more about all this from
http://www.boost-consulting.com/metaprogramming-book.html. Finally, all
that's left is to measure the number of elements in the set using mpl::size.

Quote:
Can you explain things a little bit please?

Thanks in advance!

HTH,
--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
 


Powered by phpBB © 2001, 2006 phpBB Group