|
Boost : |
From: Eric Niebler (eric_at_[hidden])
Date: 2008-03-28 03:56:10
Noah Stein wrote:
> Fernando Cacciola wrote:
>
>> 5) There is a reason why CGAL doesn't provide a distance function at all
> but
>> only a squared_distance, and I agree with that reason: sqrt() kills
>> robustness and distances are usually used for comparisons, so you seldom
>> need that.
>
> This is one of the things I think proto can help with. I'm playing around
> with a simple vector/point/matrix library just to get a feel for it. proto
> should be able to transform expressions of the sort "length(a) > length(b)"
> into "dot(a,a) > dot(b,b)". I think proper use of proto can lead to high
> levels of expressivity combined with good optimization.
Indeed, see below.
#include <iostream>
#include <boost/xpressive/proto/proto.hpp>
#include <boost/xpressive/proto/debug.hpp>
#include <boost/xpressive/proto/transform.hpp>
using namespace boost;
using namespace proto;
struct length_impl
{
friend std::ostream &operator<<(std::ostream &sout, length_impl)
{
return sout << "length_impl";
}
};
struct dot_impl
{
// dot implementation here
friend std::ostream &operator<<(std::ostream &sout, dot_impl)
{
return sout << "dot_impl";
}
};
terminal<length_impl>::type const length = {{}};
terminal<dot_impl>::type const dot = {{}};
// work around msvc bugs...
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
#define dot_impl() make<dot_impl>
#define _arg1(a) call<_arg1(a)>
#define _make_function(a,b,c) call<_make_function(a,b,c)>
#define _make_terminal(a) call<_make_terminal(a)>
#endif
// convert length(a) < length(b) to dot(a,a) < dot(b,b)
struct Convert
: when<
less<
function<terminal<length_impl>, _>
, function<terminal<length_impl>, _>
>
, _make_less(
_make_function(
_make_terminal(dot_impl())
, _arg1(_arg0)
, _arg1(_arg0)
)
, _make_function(
_make_terminal(dot_impl())
, _arg1(_arg1)
, _arg1(_arg1)
)
)
>
{};
int main()
{
int i = 0;
display_expr(length(1) < length(2));
display_expr(Convert()(length(1) < length(2), i, i));
}
This program prints:
less(
function(
terminal(length_impl)
, terminal(1)
)
, function(
terminal(length_impl)
, terminal(2)
)
)
less(
function(
terminal(dot_impl)
, terminal(1)
, terminal(1)
)
, function(
terminal(dot_impl)
, terminal(2)
, terminal(2)
)
)
In addition to demonstrating how to transform expressions, it's also a
neat demonstration of how buggy msvc is wrt function types. :-/
-- Eric Niebler Boost Consulting www.boost-consulting.com
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk