|
Boost : |
From: John Femiani (JOHN.FEMIANI_at_[hidden])
Date: 2008-05-10 19:09:19
Luke wrote:
>
> >> >yet. There are very valid reasons that the size of a
> coordinate set
> >> >should be specified at compile time for cases other than 2 or 3.
> >>
> >> You would not be using my library with these types, ...
> >
> John wrote:
> >Well then maybe I should back out of this discussion, I am interested
> in
> >a generic geometry library that will provide me with a framework to
> >write algorithms that work with any (or many) external opensource,
> >commercial, or legacy geometry libraries.
> >
> >If that is not an aim of GTL then I appologize for the noise :-)
>
> That is the aim. I don't want you to back out of the discussion.
> Instead of an n-d point concept, which provides you
> relatively little, why not extend the library to have
> explicit quaternians and homogeneous point concepts and
> algorithms specific to such geometry? Wouldn't that serve
> you better? It isn't my aim to provide those, because they
> are not used in my domain, but I do want to provide a
> framework that can be extended to include geometry that I
> don't personally need.
>
So in my imagination, CoordinatesConcept and its refinements are what we
are
talking about. There should be related concepts of PointConcept,
VectorConcept,
LineConcept, OrientationConcept, RayConcept, IntervalConcept,
SegmentConcept
and the _real_ killers are probably GeometryConcept and/or
CoordinateSystemConcept.
Most of the discussion here has been about coordinates access etc. so
here is a
rough (uncompiled) sketch of how I think a CoordinatesConcept might
look. I
am under the gun at work so If you guys tear into this I may be slow to
respond, but If this approach is appreciated I will eventually put it
into an
svn repo and actually try to compile it :)
----------------------------------------------------------------
//coordinates_concept.hpp....
namespace geometry {
template<class Coord>
struct Coordinates {
Coord coord;
typedef typename scalar_type<Coord>::type scalar;
////supporting checks I need to do...
//BOOST_CONCEPT_ASSERT((Addable<scalar, scalar>));
//BOOST_CONCEPT_ASSERT((Multiplyable<scalar, scalar>));
//BOOST_CONCEPT_ASSERT((Sunbtractable<scalar, scalar>));
//BOOST_CONCEPT_ASSERT((Dividable<scalar, scalar>));
BOOST_CONCEPT_USAGE(Coord)
{
bool bval;
bval = ::geometry::is_runtime_indexable<Coord>();
bval = ::geometry::is_runtime_indexable<Coord>::value;
size_t dim;
dim = ::geometry::dimension<Coord>();
dim = ::geometry::dimension<Coord>::value;
static_at_checker< geometry::dimension<Coord> >::apply();
}
template<class Dim>
struct static_at_checker {
Coord coord;
typedef void
result_type;
typedef mpl::prior<Dim>
static_index;
typedef typename coordinate_accessor<Coord, static_index >
accessor_type;
typedef typename accessor_type::result_type
raw_type;
BOOST_CONCEPT_ASSERT((Convertable<raw_type, scalar>));
BOOST_CONCEPT_ASSERT((UnaryFunction<accessor_type>));
//BOOST_CONCEPT_ASSERT((Addable<scalar, raw_type>));
//BOOST_CONCEPT_ASSERT((Multiplyable<scalar, raw_type>));
//BOOST_CONCEPT_ASSERT((Sunbtractable<scalar, raw_type>));
//BOOST_CONCEPT_ASSERT((Dividable<scalar, raw_type>));
//....
static void apply() {
raw_type rt = at(coord, static_index());
scalar st = at(coord, static_index());
raw_type rt = at<static_index>(coord);
scalar st = at<static_index>(coord);
static_at_checker<static_index>::apply();
}
};
template<> struct static_at_checker <mpl::int_<0> > {
static void apply(){}
};
};
}//geometry
--------------------------------------------------------------
Actually I can already see some things to do better in there but that is
_close_ to how I would do it.
There would be another CoordinateArray concept probably.
In order to adapt I would do something like this perhaps:
--------------------------------------------------------------
namespace geometry{
//named axises
namespace axis {
struct X : mpl::int_<0> {};
struct Y : mpl::int_<1> {};
struct Z : mpl::int_<2> {};
struct W : mpl::int_<3> {};
};
//Namespace for nonintrusive customization, not to be called
directly
namespace adapted {
template<class Coord> struct is_runtime_indexable
: Coord::is_runtime_indexable {};
template<class Coord> struct dimension
: Coord::dimension {};
template<class Coord> struct scalar_type
: Coord::scalar_type {};
template<class Coord, class Index> struct coordinate_accessor
: Coord::coordinate_accessor<Index> {};
}
//Public interface
template<class Coord> struct is_runtime_indexable
: geometry::adapted::is_runtime_indexable<Coord> {};
template<class Coord> struct dimension
: geometry::adapted::dimension<Coord> {};
template<class Coord> struct scalar_type
: geometry::adapted::scalar_type<Coord> {};
//Static or dynamic indexing
template<class Index, class Coord>
adapted::coordinate_accessor<Coord, Index>::result_type>::
type at(Coord& coord, Index const& index)
{
return adapted::coordinate_accessor<Coord, Index>
::apply(coord, index);
}
//Static indexing
template<class Index, class Coord>
typename enable_if_c< less_<Index, dimension<Coord> >
, adapted::coordinate_accessor<Coord, Index>
::result_type
>::
type at(Coord& coord)
{
return adapted::coordinate_accessor<Coord,
Index>::apply(coord);
}
}
------------------------------------------------------------
I would also add some other functions (at_c, size, etc) but they would
be
implimented in terms of what is here.
I think it is a lot like Fusion, but with a requirement that the element
types
have to be convertable to a common scalar type that supports the right
operations (+-*/=). And then there is the metafunction to determine
whether it
is runtime indexable or not.
Since ::geometry::adapted is a namespace it is easy to add adapted
syntax for
other concepts (like Fusion does).
Since the syntax uses free functions in the ::geometry namespace you can
include files with only the functions & metafunctions you need. (There
will be
more files in the future, that is bound to happen so we should plan on
it).
Requiring adapted syntax in the ::geometry::adapted namespace is
intended to
help avoid ADL issues etc.
MPL integral constants are used for coordinate access because they are a
convertable to integers, so static indexing should always work whenever
runtime
indexing would.
To be complete there should be header files that adapt Fusion sequences,
tuples, c-arrays and boost arrays, and CGAL points.
-- John
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk