
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