Boost logo

Boost :

From: Simonson, Lucanus J (lucanus.j.simonson_at_[hidden])
Date: 2008-05-19 18:38:34


Fernando wrote:
>>> This is probably explained somewhere but, could you state what a
>>>
>>> geometry_traits<T>::geometry_concept
>>>
>>> is?
>>
Luke wrote:
>> It is a struct that declares all functions that relate specifically
to a
>> geometry concept.
>>
Fernando wrote:
>Sorry, I meant to as what a "geometry concept" is? at a entirely
conceptual
>level.
>I ask becasue I can't infer the meaning from the name (to it feels as
it
>where "lucanus_concept" :)), nor from the particular
polygon_set_concept
>example.

geometry_traits<T> is a metafunction for looking up the conceptual type
of a geometry type T. If you pass a type which is a point type the meta
function should return point_concept, if you pass a type which is a
polygon type the meta function should return polygon_concept.
geometry_concept is just the generic name of the return value, which is
why it feels generic. In this way the geometry concept is a tag, but it
is also a namespace for functions to be declared in and may eventually
provide concept checking capabilities, including using those check to
ensure that the arguments to the functions which should model the
concept do so correctly. From that standpoint I could break it up into
three different things, a tag struct, a namespace for holding functions
related to the concept and a concept struct that provides concept
checking capabilities. On the other hand, I really like that the tag is
the namespace for passing as a template parameter and it makes sense to
me to provide concept checking eventually in the following manner:

struct point_concept {
        template <typename T>
        struct provides_get<T> {
                typedef typename result_of<point_traits<T>::get> type;
        };
        ...
        template <typename T>
        provides_get<T> get(const T& t, orientation_2d orient) {
                return point_traits<T>::get(t, orient);
        }
};
        
Do you think it would be better to change:

geometry_traits<T>::geometry_concept

to:

geometry_concept<T>::type

to make it more obviously a metafunction? I think I may have chosen a
misleading name for it, which led to confusion.

Fernando wrote:
>I meant that lazy evaluation is the job of expression templates and
that >can
>(and should IMO) be intrumented by an *external* general framework for
that
>purpose, like the pioneer PETE (http://acts.nersc.gov/pete/).
>IOW, this shouldn't by just an ad-hoc mechanism within some portions of
>your
>library if possible.

I'm not surprised to see that other people have implemented the same
basic idea. This PETE library is exactly the solution to a problem that
a colleague of mine told me he was unable to solve with C++ when I
explained my expression template to him and he saw that it solves it. I
suppose a generic solution for expression templates could be devised
that allows a functor type to be passed as the third parameter of the
template, but it would also need to add a fourth template parameter for
the type for the result that needs to be allocated and passed by
reference into the functor to store the result. Alternately, the
operation could be required to provide a lazy iterator output semantic.
At that point, however, it is more generic than most people need and I
fear that if such a library existed it wouldn't be very used.

This is what I have in mind:

template <typename l_type, typename r_type,
                typename functor_type, typename result_type>
class lazy_evaluation {
private:
        mutable result_type result_;
        mutable bool evaluated_;
        const l_type& lvalue_;
        const r_type& rvalue_;
public:
        lazy_evaluation(const l_type& lvalue, const r_type& rvalue) :
                lvalue_(lvalue), rvalue_(rvalue), evaluate_(false) {}

        //needs to be declared const so callable from a
        //const reference to this
        const result_type& evaluate() const {
                //prevent redundant evaluation
                if(!evaluated_) {
                        //modifies mutable result, which stores the
                        //result of evaluation
                        functor_type()(result_, lvalue_.evaluate(),
                                                rvalue_evaluate());
                        //modifies mutable evaluated member data
                        evaluated_ = true;
                }
                return result_;
        }
};

which factors out the expression template from my usage of it. It might
make sense for me to refactor my code in this way to provide the
abstraction between functor and expression template to eliminate
specialization of the expression template. It may also prove useful
when I implement mixed operations between axis-parallel and arbitrary
angle geometry types in which the algorithms and operators selected will
depend on the conceptual types of the input operands and I will need to
apply the same pattern several times over. I'll need to think about it
more.

Thanks,
Luke


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk