[Boost][mpl] vector_c boolean operations
Hi,
I'm new to the list so this may have been answered elsewhere (like a
FAQ for MPL) but I couldn't find it.
I've got 2 vector_c types like this
typedef vector_c
,
{}; Regards, -- Noel Belcourt
Noel Belcourt wrote:
Hi,
I'm new to the list so this may have been answered elsewhere (like a FAQ for MPL) but I couldn't find it.
I've got 2 vector_c types like this
typedef vector_c
p1; typedef vector_c p2; and a resultant type defined as
typedef vector_c
r; that I want to compare at compile time using logic like this
r = p1 || p1 && p2
I don't get it: wouldn't p1 match everything that p1 && p2 matches?
Did you mean r == p1 || p1 && p2?
You might try something like:
transform
"Noel Belcourt"
Hi,
I'm new to the list so this may have been answered elsewhere (like a FAQ for MPL) but I couldn't find it.
I've got 2 vector_c types like this
typedef vector_c
p1; typedef vector_c p2; and a resultant type defined as
typedef vector_c
r;
Resultant from what?
that I want to compare at compile time using logic like this
r = p1 || p1 && p2
That would be equivalent to r = p1. Why go to all that trouble? Or
do you mean
r == p1 || p1 && p2
??
Anyway, what does it mean to use the logical && operator on two
sequences? Do you want elementwise comparison? Do you want the same
for r == p1? The usual meaning is to compare all elements and produce
a scalar boolean, which would then be incompatible with the vector of
bools produced by p1 && p2. Maybe you mean something like;
mpl::transform<
mpl::transform
This pseudo code is what I want to do but I know this doesn't work. Can anyone can suggest a better approach?
template
struct validate_checkin : boost::mpl::equal< boost::mpl::placeholders::_1, boost::mpl::or_< boost::mpl::placeholders::_2, boost::mpl::and_< boost::mpl::placeholders::_2, boost::mpl::placeholders::_3 >, ,
{};
Ugh; do yourself a favor and apply a couple of namespace aliases at
least; the whole point of those placeholders is that they're supposed
to increase readability!
Simplifying:
namespace mpl = boost::mpl;
using namespace mpl::placeholders;
template
On Sep 29, 2005, at 7:45 PM, David Abrahams wrote:
"Noel Belcourt"
writes: r = p1 || p1 && p2
That would be equivalent to r = p1. Why go to all that trouble? Or do you mean
r == p1 || p1 && p2
Yes, that's what I meant.
Anyway, what does it mean to use the logical && operator on two sequences? Do you want elementwise comparison?
Yes, element-wise comparison.
Do you want the same for r == p1?
Yes.
The usual meaning is to compare all elements and produce a scalar boolean, which would then be incompatible with the vector of bools produced by p1 && p2. Maybe you mean something like;
mpl::transform< mpl::transform
>::type , mpl::transform >::type , mpl::or_<_,_> ::type
This looks reasonable. Transform returns a new sequence produced by
applying the binary operation to a pair of elements from the input
sequences.
Let me see if I understand this.
So if I want to perform an element-wise mpl::or operation of two
sequences (r, p1) and then test the resulting sequence for equivalence
to the input sequence, something like this should work since as you
observe below, mpl::equal will compare two sequences and yield a scalar
boolean.
BOOST_STATIC_ASSERT((
equal<
r
, transform
::type::value ));
Ugh; do yourself a favor and apply a couple of namespace aliases at least; the whole point of those placeholders is that they're supposed to increase readability!
Duly noted.
It seems to me that you also have several conceptual problems here. First, you have perfectly good metafunction parameters here that you can use; what are the placeholders supposed to be doing? Placeholders only have an effect in a context where an MPL placeholder expression can be used, e.g. in an argument to mpl::apply<...>. Why not just use R, P1, and P2 directly?
In this case I could.
Second, you seem to be trying to use the equal algorithm, which operates on sequences, on the results of some invocation of mpl::or_, which does not return a sequence but a scalar bool-valued MPL integral constant.
True, I was confused about this point. So I'll use transform to generate a sequence representing the element-wise binary operation and then use equal. Thanks, -- Noel
"Noel Belcourt"
Let me see if I understand this.
So if I want to perform an element-wise mpl::or operation of two sequences (r, p1) and then test the resulting sequence for equivalence to the input sequence, something like this should work since as you observe below, mpl::equal will compare two sequences and yield a scalar boolean.
BOOST_STATIC_ASSERT(( equal< r , transform
>::type ::type::value ));
Yes.
BOOST_MPL_ASSERT((equal
Second, you seem to be trying to use the equal algorithm, which operates on sequences, on the results of some invocation of mpl::or_, which does not return a sequence but a scalar bool-valued MPL integral constant.
True, I was confused about this point. So I'll use transform to generate a sequence representing the element-wise binary operation and then use equal.
Great; good luck! -- Dave Abrahams Boost Consulting www.boost-consulting.com
On Oct 1, 2005, at 6:57 PM, David Abrahams wrote:
"Noel Belcourt"
writes: So if I want to perform an element-wise mpl::or operation of two sequences (r, p1) and then test the resulting sequence for equivalence to the input sequence, something like this should work since as you observe below, mpl::equal will compare two sequences and yield a scalar boolean.
BOOST_MPL_ASSERT((equal
>::type>));
One more observation about this, this code doesn't compile if r and p1
are a vector_c
BOOST_MPL_ASSERT(( equal_to< find< zip_view
, not_equal_to ,or_ ,second<_> > ::type , end
>::type ))
I'll be sure to read up on zip_view and try this out. Thanks for your help. -- Noel
"Noel Belcourt"
On Oct 1, 2005, at 6:57 PM, David Abrahams wrote:
"Noel Belcourt"
writes: So if I want to perform an element-wise mpl::or operation of two sequences (r, p1) and then test the resulting sequence for equivalence to the input sequence, something like this should work since as you observe below, mpl::equal will compare two sequences and yield a scalar boolean.
BOOST_MPL_ASSERT((equal
>::type>)); One more observation about this, this code doesn't compile if r and p1 are a vector_c
or a vector_c with CW 9.5 on Tiger 10.4.2. The compiler output is attached. For example, if r and p1 are declared as follows, the code will not compile.
typedef vector_c
r,p1; BOOST_MPL_ASSERT(( equal >::type>)); The problem seems to be that the sequence produced by invoking transform using a boolean binary function is a different type than vector_c
.
I think that's not really the issue. I think the problem is that the _element_ types of those two sequuences are not identical.
The fix is trivial.
typedef vector_c
r,p1; BOOST_MPL_ASSERT(( equal >::type, transform >::type>)); While clunky, this works, and also works if we declare r and p1 as vector_c
.
Actually I think that's technically nonportable.
I'm guessing the right thing to do is use find, one way or the other.
This is
typedef transform
Just want to be sure that this is known and expected behavior?
I'm actually unsure. Aleksey?
BOOST_MPL_ASSERT(( equal_to<
I think this should be is_same. Sorry for the mistake.
find< zip_view
, not_equal_to ,or_ ,second<_> > ::type , end
>::type ))
I'll be sure to read up on zip_view and try this out.
Thanks for your help.
-- Noel
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
-- Dave Abrahams Boost Consulting www.boost-consulting.com
David Abrahams writes:
"Noel Belcourt"
writes: On Oct 1, 2005, at 6:57 PM, David Abrahams wrote:
"Noel Belcourt"
writes: So if I want to perform an element-wise mpl::or operation of two sequences (r, p1) and then test the resulting sequence for equivalence to the input sequence, something like this should work since as you observe below, mpl::equal will compare two sequences and yield a scalar boolean.
BOOST_MPL_ASSERT((equal
>::type>)); One more observation about this, this code doesn't compile if r and p1 are a vector_c
or a vector_c with CW 9.5 on Tiger 10.4.2. The compiler output is attached. For example, if r and p1 are declared as follows, the code will not compile.
typedef vector_c
r,p1; BOOST_MPL_ASSERT(( equal >::type>)); The problem seems to be that the sequence produced by invoking transform using a boolean binary function is a different type than vector_c
. I think that's not really the issue. I think the problem is that the _element_ types of those two sequuences are not identical.
Yep. The default predicate for 'equal' is 'is_same', which means that
the algorithm compares elements' type identity instead of their values
(and for the numeric operations, the former is seldom guaranteed). Try
typedef vector_c
Just want to be sure that this is known and expected behavior?
I'm actually unsure. Aleksey?
Yes, it is. -- Aleksey Gurtovoy MetaCommunications Engineering
participants (4)
-
Aleksey Gurtovoy
-
David Abrahams
-
Noel Belcourt
-
Simon Buchan