$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r57364 - in sandbox/ggl/formal_review/boost/ggl: . algorithms algorithms/detail algorithms/overlay arithmetic core extensions extensions/gis extensions/gis/geographic extensions/gis/geographic/detail extensions/gis/geographic/strategies extensions/gis/io extensions/gis/io/wkb extensions/gis/io/wkb/detail extensions/gis/io/wkt extensions/gis/io/wkt/detail extensions/io extensions/io/svg geometries geometries/adapted geometries/concepts geometries/concepts/detail geometries/register iterators multi multi/algorithms multi/algorithms/detail multi/algorithms/overlay multi/core multi/geometries multi/geometries/concepts multi/iterators multi/strategies multi/strategies/cartesian multi/util policies policies/relate strategies strategies/agnostic strategies/cartesian strategies/concepts strategies/spherical strategies/transform util
From: barend.gehrels_at_[hidden]
Date: 2009-11-04 12:10:24
Author: barendgehrels
Date: 2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
New Revision: 57364
URL: http://svn.boost.org/trac/boost/changeset/57364
Log:
Filled formal review tree
Added:
   sandbox/ggl/formal_review/boost/ggl/
   sandbox/ggl/formal_review/boost/ggl/algorithms/
   sandbox/ggl/formal_review/boost/ggl/algorithms/append.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/algorithms/area.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/algorithms/assign.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/algorithms/centroid.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/algorithms/clear.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/algorithms/combine.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/algorithms/convert.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/algorithms/convex_hull.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/algorithms/correct.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/algorithms/detail/
   sandbox/ggl/formal_review/boost/ggl/algorithms/detail/calculate_null.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/algorithms/detail/calculate_sum.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/algorithms/detail/disjoint.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/algorithms/detail/not.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/algorithms/detail/point_on_border.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/algorithms/disjoint.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/algorithms/distance.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/algorithms/envelope.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/algorithms/equals.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/algorithms/for_each.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/algorithms/get_section.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/algorithms/intersection.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/algorithms/intersects.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/algorithms/length.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/algorithms/make.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/algorithms/num_points.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/algorithms/overlaps.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/algorithms/overlay/
   sandbox/ggl/formal_review/boost/ggl/algorithms/overlay/adapt_turns.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/algorithms/overlay/assemble.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/algorithms/overlay/clip_linestring.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/algorithms/overlay/copy_segments.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/algorithms/overlay/enrich_intersection_points.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/algorithms/overlay/get_intersection_points.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/algorithms/overlay/intersection_point.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/algorithms/overlay/merge_intersection_points.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/algorithms/overlay/segment_identifier.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/algorithms/overlay/self_intersection_points.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/algorithms/overlay/sort_interior_rings.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/algorithms/overlay/traverse.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/algorithms/parse.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/algorithms/perimeter.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/algorithms/sectionalize.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/algorithms/simplify.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/algorithms/transform.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/algorithms/union.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/algorithms/within.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/arithmetic/
   sandbox/ggl/formal_review/boost/ggl/arithmetic/arithmetic.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/arithmetic/dot_product.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/core/
   sandbox/ggl/formal_review/boost/ggl/core/access.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/core/coordinate_dimension.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/core/coordinate_system.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/core/coordinate_type.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/core/cs.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/core/exception.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/core/exterior_ring.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/core/geometry_id.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/core/interior_rings.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/core/is_linear.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/core/is_multi.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/core/point_order.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/core/point_type.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/core/radian_access.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/core/replace_point_type.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/core/reverse_dispatch.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/core/ring_type.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/core/tag.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/core/tags.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/core/topological_dimension.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/extensions/
   sandbox/ggl/formal_review/boost/ggl/extensions/gis/
   sandbox/ggl/formal_review/boost/ggl/extensions/gis/geographic/
   sandbox/ggl/formal_review/boost/ggl/extensions/gis/geographic/detail/
   sandbox/ggl/formal_review/boost/ggl/extensions/gis/geographic/detail/ellipsoid.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/extensions/gis/geographic/strategies/
   sandbox/ggl/formal_review/boost/ggl/extensions/gis/geographic/strategies/andoyer.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/extensions/gis/geographic/strategies/area_huiller_earth.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/extensions/gis/geographic/strategies/dms_parser.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/extensions/gis/geographic/strategies/vincenty.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/extensions/gis/io/
   sandbox/ggl/formal_review/boost/ggl/extensions/gis/io/wkb/
   sandbox/ggl/formal_review/boost/ggl/extensions/gis/io/wkb/detail/
   sandbox/ggl/formal_review/boost/ggl/extensions/gis/io/wkb/detail/endian.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/extensions/gis/io/wkb/detail/ogc.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/extensions/gis/io/wkb/detail/parser.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/extensions/gis/io/wkb/read_wkb.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/extensions/gis/io/wkb/utility.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/extensions/gis/io/wkt/
   sandbox/ggl/formal_review/boost/ggl/extensions/gis/io/wkt/detail/
   sandbox/ggl/formal_review/boost/ggl/extensions/gis/io/wkt/detail/wkt.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/extensions/gis/io/wkt/detail/wkt_multi.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/extensions/gis/io/wkt/read_wkt.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/extensions/gis/io/wkt/read_wkt_multi.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/extensions/gis/io/wkt/stream_wkt.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/extensions/gis/io/wkt/wkt.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/extensions/gis/io/wkt/write_wkt.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/extensions/gis/io/wkt/write_wkt_multi.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/extensions/io/
   sandbox/ggl/formal_review/boost/ggl/extensions/io/svg/
   sandbox/ggl/formal_review/boost/ggl/extensions/io/svg/write_svg.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/extensions/io/svg/write_svg_multi.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/geometries/
   sandbox/ggl/formal_review/boost/ggl/geometries/adapted/
   sandbox/ggl/formal_review/boost/ggl/geometries/adapted/boost_array_as_linestring.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/geometries/adapted/boost_array_as_ring.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/geometries/adapted/c_array.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/geometries/adapted/c_array_cartesian.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/geometries/adapted/std_as_linestring.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/geometries/adapted/std_as_ring.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/geometries/adapted/std_pair_as_segment.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/geometries/adapted/tuple.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/geometries/adapted/tuple_cartesian.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/geometries/box.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/geometries/cartesian2d.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/geometries/cartesian3d.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/geometries/concepts/
   sandbox/ggl/formal_review/boost/ggl/geometries/concepts/box_concept.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/geometries/concepts/check.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/geometries/concepts/detail/
   sandbox/ggl/formal_review/boost/ggl/geometries/concepts/detail/check_append.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/geometries/concepts/detail/check_clear.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/geometries/concepts/linestring_concept.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/geometries/concepts/point_concept.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/geometries/concepts/polygon_concept.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/geometries/concepts/ring_concept.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/geometries/concepts/segment_concept.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/geometries/geometries.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/geometries/linear_ring.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/geometries/linestring.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/geometries/point.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/geometries/point_xy.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/geometries/polygon.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/geometries/register/
   sandbox/ggl/formal_review/boost/ggl/geometries/register/box.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/geometries/register/linestring.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/geometries/register/point.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/geometries/register/ring.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/geometries/register/segment.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/geometries/segment.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/ggl.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/iterators/
   sandbox/ggl/formal_review/boost/ggl/iterators/base.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/iterators/circular_iterator.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/iterators/ever_circling_iterator.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/iterators/range_type.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/iterators/segment_iterator.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/multi/
   sandbox/ggl/formal_review/boost/ggl/multi/algorithms/
   sandbox/ggl/formal_review/boost/ggl/multi/algorithms/area.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/multi/algorithms/centroid.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/multi/algorithms/convex_hull.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/multi/algorithms/correct.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/multi/algorithms/detail/
   sandbox/ggl/formal_review/boost/ggl/multi/algorithms/detail/modify_with_predicate.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/multi/algorithms/detail/multi_sum.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/multi/algorithms/distance.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/multi/algorithms/envelope.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/multi/algorithms/for_each.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/multi/algorithms/get_section.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/multi/algorithms/intersection.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/multi/algorithms/length.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/multi/algorithms/num_points.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/multi/algorithms/overlay/
   sandbox/ggl/formal_review/boost/ggl/multi/algorithms/overlay/copy_segments.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/multi/algorithms/overlay/get_intersection_points.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/multi/algorithms/perimeter.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/multi/algorithms/sectionalize.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/multi/algorithms/simplify.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/multi/algorithms/transform.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/multi/algorithms/within.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/multi/core/
   sandbox/ggl/formal_review/boost/ggl/multi/core/geometry_id.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/multi/core/is_multi.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/multi/core/point_type.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/multi/core/ring_type.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/multi/core/tags.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/multi/core/topological_dimension.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/multi/geometries/
   sandbox/ggl/formal_review/boost/ggl/multi/geometries/concepts/
   sandbox/ggl/formal_review/boost/ggl/multi/geometries/concepts/check.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/multi/geometries/concepts/multi_linestring_concept.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/multi/geometries/concepts/multi_point_concept.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/multi/geometries/concepts/multi_polygon_concept.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/multi/geometries/multi_linestring.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/multi/geometries/multi_point.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/multi/geometries/multi_polygon.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/multi/iterators/
   sandbox/ggl/formal_review/boost/ggl/multi/iterators/range_type.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/multi/multi.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/multi/strategies/
   sandbox/ggl/formal_review/boost/ggl/multi/strategies/cartesian/
   sandbox/ggl/formal_review/boost/ggl/multi/strategies/cartesian/centroid_average.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/multi/strategies/centroid.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/multi/util/
   sandbox/ggl/formal_review/boost/ggl/multi/util/for_each_range.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/multi/util/write_dsv.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/policies/
   sandbox/ggl/formal_review/boost/ggl/policies/compare.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/policies/relate/
   sandbox/ggl/formal_review/boost/ggl/policies/relate/direction.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/policies/relate/intersection_points.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/policies/relate/tupled.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/strategies/
   sandbox/ggl/formal_review/boost/ggl/strategies/agnostic/
   sandbox/ggl/formal_review/boost/ggl/strategies/agnostic/hull_graham_andrew.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/strategies/agnostic/point_in_poly_winding.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/strategies/agnostic/simplify_douglas_peucker.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/strategies/area.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/strategies/area_result.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/strategies/cartesian/
   sandbox/ggl/formal_review/boost/ggl/strategies/cartesian/area_by_triangles.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/strategies/cartesian/cart_intersect.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/strategies/cartesian/centroid_bashein_detmer.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/strategies/cartesian/distance_projected_point.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/strategies/cartesian/distance_pythagoras.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/strategies/cartesian/point_in_poly_crossings_multiply.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/strategies/cartesian/point_in_poly_franklin.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/strategies/cartesian/side_by_triangle.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/strategies/centroid.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/strategies/compare.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/strategies/concepts/
   sandbox/ggl/formal_review/boost/ggl/strategies/concepts/area_concept.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/strategies/concepts/centroid_concept.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/strategies/concepts/convex_hull_concept.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/strategies/concepts/distance_concept.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/strategies/concepts/simplify_concept.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/strategies/concepts/within_concept.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/strategies/convex_hull.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/strategies/distance.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/strategies/distance_result.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/strategies/intersection_result.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/strategies/length_result.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/strategies/parse.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/strategies/point_in_poly.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/strategies/side.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/strategies/spherical/
   sandbox/ggl/formal_review/boost/ggl/strategies/spherical/area_huiller.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/strategies/spherical/compare_circular.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/strategies/spherical/distance_cross_track.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/strategies/spherical/distance_haversine.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/strategies/strategies.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/strategies/strategy_transform.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/strategies/tags.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/strategies/transform/
   sandbox/ggl/formal_review/boost/ggl/strategies/transform.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/strategies/transform/inverse_transformer.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/strategies/transform/map_transformer.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/strategies/transform/matrix_transformers.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/util/
   sandbox/ggl/formal_review/boost/ggl/util/add_const_if_c.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/util/as_range.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/util/copy.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/util/for_each_coordinate.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/util/for_each_range.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/util/math.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/util/range_iterator_const_if_c.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/util/select_calculation_type.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/util/select_coordinate_type.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/util/select_most_precise.hpp   (contents, props changed)
   sandbox/ggl/formal_review/boost/ggl/util/write_dsv.hpp   (contents, props changed)
Added: sandbox/ggl/formal_review/boost/ggl/algorithms/append.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/algorithms/append.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,189 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_APPEND_HPP
+#define GGL_ALGORITHMS_APPEND_HPP
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/point_type.hpp>
+#include <ggl/core/tags.hpp>
+
+#include <ggl/geometries/concepts/check.hpp>
+
+#include <ggl/util/copy.hpp>
+
+namespace ggl
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace append {
+
+template <typename Geometry, typename Point, bool UseStd>
+struct append_point {};
+
+template <typename Geometry, typename Point>
+struct append_point<Geometry, Point, true>
+{
+    static inline void apply(Geometry& geometry, Point const& point, int , int )
+    {
+        typename point_type<Geometry>::type point_type;
+
+        copy_coordinates(point, point_type);
+        geometry.push_back(point_type);
+    }
+};
+
+template <typename Geometry, typename Point>
+struct append_point<Geometry, Point, false>
+{
+    static inline void apply(Geometry& geometry, Point const& point,
+                int ring_index, int multi_index)
+    {
+        traits::append_point<Geometry, Point>::apply(geometry, point,
+                    ring_index, multi_index);
+    }
+};
+
+template <typename Geometry, typename Range, bool UseStd>
+struct append_range
+{
+    typedef typename boost::range_value<Range>::type point_type;
+
+    static inline void apply(Geometry& geometry, Range const& range,
+                int ring_index, int multi_index)
+    {
+        for (typename boost::range_const_iterator<Range>::type
+            it = boost::begin(range);
+             it != boost::end(range);
+             ++it)
+        {
+            append_point<Geometry, point_type, UseStd>::apply(geometry, *it,
+                        ring_index, multi_index);
+        }
+    }
+};
+
+template <typename Polygon, typename Point, bool Std>
+struct point_to_poly
+{
+    typedef typename ring_type<Polygon>::type range_type;
+
+    static inline void apply(Polygon& polygon, Point const& point,
+                int ring_index, int )
+    {
+        if (ring_index == -1)
+        {
+            append_point<range_type, Point, Std>::apply(
+                        exterior_ring(polygon), point, -1, -1);
+        }
+        else if (ring_index < int(num_interior_rings(polygon)))
+        {
+            append_point<range_type, Point, Std>::apply(
+                        interior_rings(polygon)[ring_index], point, -1, -1);
+        }
+    }
+};
+
+template <typename Polygon, typename Range, bool Std>
+struct range_to_poly
+{
+    typedef typename ring_type<Polygon>::type ring_type;
+
+    static inline void apply(Polygon& polygon, Range const& range,
+                int ring_index, int )
+    {
+        if (ring_index == -1)
+        {
+            append_range<ring_type, Range, Std>::apply(
+                        exterior_ring(polygon), range, -1, -1);
+        }
+        else if (ring_index < int(num_interior_rings(polygon)))
+        {
+            append_range<ring_type, Range, Std>::apply(
+                        interior_rings(polygon)[ring_index], range, -1, -1);
+        }
+    }
+};
+
+}} // namespace detail::append
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+// (RoP = range or point, Std = use std library)
+
+// Default case (where RoP will be range/array/etc)
+template <typename Tag, typename TagRoP, typename G, typename RoP, bool Std>
+struct append : detail::append::append_range<G, RoP, Std> {};
+
+// Append a point to any geometry
+template <typename Tag, typename G, typename P, bool Std>
+struct append<Tag, point_tag, G, P, Std>
+    : detail::append::append_point<G, P, Std> {};
+
+// Never possible to append anything to a point/box/n-sphere
+template <typename TagRoP, typename Point, typename RoP, bool Std>
+struct append<point_tag, TagRoP, Point, RoP, Std> {};
+
+template <typename TagRoP, typename Box, typename RoP, bool Std>
+struct append<box_tag, TagRoP, Box, RoP, Std> {};
+
+
+template <typename Polygon, typename TagRange, typename Range, bool Std>
+struct append<polygon_tag, TagRange, Polygon, Range, Std>
+        : detail::append::range_to_poly<Polygon, Range, Std> {};
+
+template <typename Polygon, typename Point, bool Std>
+struct append<polygon_tag, point_tag, Polygon, Point, Std>
+        : detail::append::point_to_poly<Polygon, Point, Std> {};
+
+// Multi-linestring and multi-polygon might either implement traits
+// or use standard...
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+    \brief Appends one or more points to a linestring, ring, polygon, multi
+    \ingroup access
+    \param geometry a geometry
+    \param range_or_point the point or range to add
+    \param ring_index the index of the ring in case of a polygon:
+        exterior ring (-1, the default) or  interior ring index
+    \param multi_index reserved for multi polygons
+ */
+template <typename Geometry, typename RoP>
+inline void append(Geometry& geometry, RoP const& range_or_point,
+            int ring_index = -1, int multi_index = 0)
+{
+    concept::check<Geometry>();
+
+    typedef typename boost::remove_const<Geometry>::type ncg_type;
+
+    dispatch::append
+        <
+            typename tag<Geometry>::type,
+            typename tag<RoP>::type,
+            ncg_type,
+            RoP,
+            traits::use_std<ncg_type>::value
+        >::apply(geometry, range_or_point, ring_index, multi_index);
+}
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_APPEND_HPP
Added: sandbox/ggl/formal_review/boost/ggl/algorithms/area.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/algorithms/area.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,259 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_AREA_HPP
+#define GGL_ALGORITHMS_AREA_HPP
+
+#include <boost/mpl/if.hpp>
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+
+#include <ggl/core/point_order.hpp>
+#include <ggl/core/exterior_ring.hpp>
+#include <ggl/core/interior_rings.hpp>
+#include <ggl/core/ring_type.hpp>
+
+#include <ggl/geometries/concepts/check.hpp>
+
+#include <ggl/algorithms/detail/calculate_null.hpp>
+#include <ggl/algorithms/detail/calculate_sum.hpp>
+
+#include <ggl/strategies/area.hpp>
+#include <ggl/strategies/area_result.hpp>
+
+#include <ggl/strategies/concepts/area_concept.hpp>
+
+#include <ggl/util/math.hpp>
+
+/*!
+\defgroup area area: calculate area of a geometry
+
+\par Performance
+2776 * 1000 area calculations are done in 0.11 seconds
+(http://trac.osgeo.org/ggl/wiki/Performance#Area1)
+
+\par Coordinate systems and strategies
+Area calculation can be done in Cartesian and in spherical/geographic
+coordinate systems.
+
+\par Geometries
+The area algorithm calculates the surface area of all geometries
+having a surface: box, polygon, multi_polygon. The units are the square of
+the units used for the points defining the surface. If the polygon is defined
+in meters, the area is in square meters.
+
+\par Example:
+Example showing area calculation of polygons built
+\dontinclude doxygen_1.cpp
+\skip example_area_polygon()
+\line {
+\until }
+
+*/
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace area {
+
+template<typename Box, typename Strategy>
+struct box_area
+{
+    typedef typename coordinate_type<Box>::type return_type;
+
+    static inline return_type apply(Box const& box, Strategy const&)
+    {
+        // Currently only works for 2D Cartesian boxes
+        assert_dimension<Box, 2>();
+
+        return_type const dx = get<max_corner, 0>(box)
+                - get<min_corner, 0>(box);
+        return_type const dy = get<max_corner, 1>(box)
+                - get<min_corner, 1>(box);
+
+        return dx * dy;
+    }
+};
+
+
+
+
+/*!
+    \brief Calculate area of a ring, specialized per order
+ */
+template
+<
+    typename Ring,
+    order_selector Order,
+    // closing_selector Closed -- for now assuming CLOSED, p(0) == p(n-1)
+    typename Strategy
+>
+struct ring_area
+{};
+
+
+template<typename Ring, typename Strategy>
+struct ring_area<Ring, clockwise, Strategy>
+{
+    BOOST_CONCEPT_ASSERT( (ggl::concept::AreaStrategy<Strategy>) );
+
+    typedef typename Strategy::return_type type;
+
+    static inline type apply(Ring const& ring, Strategy const& strategy)
+    {
+        assert_dimension<Ring, 2>();
+
+        // A closed linear_ring has at least four points,
+        // if not, there is no (zero) area
+        if (boost::size(ring) < 4)
+        {
+            return type();
+        }
+
+        typedef typename boost::range_const_iterator<Ring>::type iterator_type;
+
+        typename Strategy::state_type state;
+
+        iterator_type it = boost::begin(ring);
+        for (iterator_type previous = it++;
+            it != boost::end(ring);
+            previous = it++)
+        {
+            strategy.apply(*previous, *it, state);
+        }
+        return strategy.result(state);
+
+    }
+};
+
+template<typename Ring, typename Strategy>
+struct ring_area<Ring, counterclockwise, Strategy>
+{
+    typedef typename Strategy::return_type type;
+    static inline type apply(Ring const& ring, Strategy const& strategy)
+    {
+        // Counter clockwise rings negate the area result
+        return -ring_area<Ring, clockwise, Strategy>::apply(ring, strategy);
+    }
+};
+
+
+}} // namespace detail::area
+
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch {
+
+template
+<
+    typename Tag,
+    typename Geometry,
+    order_selector Order,
+    typename Strategy
+>
+struct area
+    : detail::calculate_null
+        <
+            typename Strategy::return_type,
+            Geometry,
+            Strategy
+        > {};
+
+
+template <typename Geometry, order_selector Order, typename Strategy>
+struct area<box_tag, Geometry, Order, Strategy>
+    : detail::area::box_area<Geometry, Strategy>
+{};
+
+
+// Area of ring currently returns area of closed rings but it might be argued
+// that it is 0.0, because a ring is just a line.
+template <typename Geometry, order_selector Order, typename Strategy>
+struct area<ring_tag, Geometry, Order, Strategy>
+    : detail::area::ring_area<Geometry, Order, Strategy>
+{};
+
+template <typename Polygon, order_selector Order, typename Strategy>
+struct area<polygon_tag, Polygon, Order, Strategy>
+    : detail::calculate_polygon_sum
+        <
+            typename Strategy::return_type,
+            Polygon,
+            Strategy,
+            detail::area::ring_area
+                <
+                    typename ring_type<Polygon>::type,
+                    Order,
+                    Strategy
+                >
+        >
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+
+/*!
+    \brief Calculate area of a geometry
+    \ingroup area
+    \details The function area returns the area of a polygon, ring, box
+    using the default area-calculation strategy. Strategies are
+    provided for cartesian and spherical coordinate systems
+    The geometries should correct, polygons should be closed
+    and according to the specified orientation (clockwise/counter clockwise)
+    \param geometry a geometry
+    \return the area
+ */
+template <typename Geometry>
+inline typename area_result<Geometry>::type area(Geometry const& geometry)
+{
+    concept::check<const Geometry>();
+
+    typedef typename area_result<Geometry>::strategy_type strategy_type;
+
+    return dispatch::area
+        <
+            typename tag<Geometry>::type,
+            Geometry,
+            ggl::point_order<Geometry>::value,
+            strategy_type
+        >::apply(geometry, strategy_type());
+}
+
+/*!
+    \brief Calculate area of a geometry using a specified strategy
+    \ingroup area
+    \details This version of area calculation takes a strategy
+    \param geometry a geometry
+    \param strategy the strategy to calculate area.
+        Especially for spherical areas there are some approaches.
+    \return the area
+ */
+template <typename Geometry, typename Strategy>
+inline typename Strategy::return_type area(
+        Geometry const& geometry, Strategy const& strategy)
+{
+    concept::check<const Geometry>();
+
+    return dispatch::area
+        <
+            typename tag<Geometry>::type,
+            Geometry,
+            ggl::point_order<Geometry>::value,
+            Strategy
+        >::apply(geometry, strategy);
+}
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_AREA_HPP
Added: sandbox/ggl/formal_review/boost/ggl/algorithms/assign.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/algorithms/assign.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,522 @@
+// Generic Geometry Library
+//
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_ASSIGN_HPP
+#define GGL_ALGORITHMS_ASSIGN_HPP
+
+#include <cstddef>
+
+#include <boost/concept/requires.hpp>
+#include <boost/concept_check.hpp>
+#include <boost/numeric/conversion/bounds.hpp>
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <ggl/algorithms/append.hpp>
+#include <ggl/algorithms/clear.hpp>
+#include <ggl/core/access.hpp>
+#include <ggl/core/exterior_ring.hpp>
+#include <ggl/core/tags.hpp>
+
+#include <ggl/geometries/concepts/check.hpp>
+
+
+#include <ggl/util/copy.hpp>
+#include <ggl/util/for_each_coordinate.hpp>
+
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace assign {
+
+template <typename CoordinateType>
+struct assign_operation
+{
+    inline assign_operation(CoordinateType const& value)
+        : m_value(value)
+    {}
+
+    template <typename P, std::size_t I>
+    inline void apply(P& point) const
+    {
+        set<I>(point, m_value);
+    }
+
+private:
+
+    CoordinateType m_value;
+};
+
+
+/*!
+    \brief Assigns all coordinates of a specific point to a value
+    \ingroup access
+    \details
+    \param p Point
+    \param value Value which is assigned to all coordinates of point p
+ */
+template <typename Point>
+inline void assign_value(Point& p,
+        typename coordinate_type<Point>::type const& value)
+{
+    for_each_coordinate(p,
+            assign_operation<typename coordinate_type<Point>::type>(value));
+}
+
+
+
+template
+<
+    typename Box, std::size_t Index,
+    std::size_t Dimension, std::size_t DimensionCount
+>
+struct initialize
+{
+    typedef typename coordinate_type<Box>::type coordinate_type;
+
+    static inline void apply(Box& box, coordinate_type const& value)
+    {
+        set<Index, Dimension>(box, value);
+        initialize<Box, Index, Dimension + 1, DimensionCount>::apply(box, value);
+    }
+};
+
+
+template <typename Box, std::size_t Index, std::size_t DimensionCount>
+struct initialize<Box, Index, DimensionCount, DimensionCount>
+{
+    typedef typename coordinate_type<Box>::type coordinate_type;
+
+    static inline void apply(Box&,  coordinate_type const& )
+    {}
+};
+
+
+template <typename Point>
+struct assign_zero_point
+{
+    static inline void apply(Point& point)
+    {
+        typedef typename coordinate_type<Point>::type coordinate_type;
+        assign_value(point, 0);
+    }
+};
+
+
+template <typename Box>
+struct assign_inverse_box
+{
+    typedef typename point_type<Box>::type point_type;
+
+    static inline void apply(Box& box)
+    {
+        typedef typename coordinate_type<point_type>::type coordinate_type;
+
+        initialize
+            <
+                Box, min_corner, 0, dimension<Box>::type::value
+            >::apply(
+            box, boost::numeric::bounds<coordinate_type>::highest());
+        initialize
+            <
+                Box, max_corner, 0, dimension<Box>::type::value
+            >::apply(
+            box, boost::numeric::bounds<coordinate_type>::lowest());
+    }
+};
+
+
+template <typename Box>
+struct assign_zero_box
+{
+    static inline void apply(Box& box)
+    {
+        typedef typename coordinate_type<Box>::type coordinate_type;
+
+        initialize
+            <
+                Box, min_corner, 0, dimension<Box>::type::value
+            >::apply(box, coordinate_type());
+        initialize
+            <
+                Box, max_corner, 0, dimension<Box>::type::value
+            >::apply(box, coordinate_type());
+    }
+};
+
+
+template
+<
+    std::size_t Corner1, std::size_t Corner2,
+    typename Box, typename Point
+>
+inline void assign_box_2d_corner(Box const& box, Point& point)
+{
+    // Be sure both are 2-Dimensional
+    assert_dimension<Box, 2>();
+    assert_dimension<Point, 2>();
+
+    // Copy coordinates
+    typedef typename coordinate_type<Point>::type coordinate_type;
+
+    set<0>(point, boost::numeric_cast<coordinate_type>(get<Corner1, 0>(box)));
+    set<1>(point, boost::numeric_cast<coordinate_type>(get<Corner2, 1>(box)));
+}
+
+
+
+template
+<
+    typename Geometry, typename Point,
+    std::size_t Index,
+    std::size_t Dimension, std::size_t DimensionCount
+>
+struct assign_point_to_index
+{
+
+    static inline void apply(Point const& point, Geometry& geometry)
+    {
+        ggl::set<Index, Dimension>(geometry, boost::numeric_cast
+            <
+                typename coordinate_type<Geometry>::type
+            >(ggl::get<Dimension>(point)));
+
+        assign_point_to_index
+            <
+                Geometry, Point, Index, Dimension + 1, DimensionCount
+            >::apply(point, geometry);
+    }
+};
+
+template
+<
+    typename Geometry, typename Point,
+    std::size_t Index,
+    std::size_t DimensionCount
+>
+struct assign_point_to_index
+    <
+        Geometry, Point,
+        Index,
+        DimensionCount, DimensionCount
+    >
+{
+    static inline void apply(Point const& , Geometry& )
+    {
+    }
+};
+
+
+template
+<
+    typename Geometry, typename Point,
+    std::size_t Index,
+    std::size_t Dimension, std::size_t DimensionCount
+>
+struct assign_point_from_index
+{
+
+    static inline void apply(Geometry const& geometry, Point& point)
+    {
+        ggl::set<Dimension>( point, boost::numeric_cast
+            <
+                typename coordinate_type<Geometry>::type
+            >(ggl::get<Index, Dimension>(geometry)));
+
+        assign_point_from_index
+            <
+                Geometry, Point, Index, Dimension + 1, DimensionCount
+            >::apply(geometry, point);
+    }
+};
+
+template
+<
+    typename Geometry, typename Point,
+    std::size_t Index,
+    std::size_t DimensionCount
+>
+struct assign_point_from_index
+    <
+        Geometry, Point,
+        Index,
+        DimensionCount, DimensionCount
+    >
+{
+    static inline void apply(Geometry const&, Point&)
+    {
+    }
+};
+
+
+
+}} // namespace detail::assign
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename GeometryTag, typename Geometry, std::size_t DimensionCount>
+struct assign {};
+
+template <typename Point>
+struct assign<point_tag, Point, 2>
+{
+    typedef typename coordinate_type<Point>::type coordinate_type;
+
+    template <typename T>
+    static inline void apply(Point& point, T const& c1, T const& c2)
+    {
+        set<0>(point, boost::numeric_cast<coordinate_type>(c1));
+        set<1>(point, boost::numeric_cast<coordinate_type>(c2));
+    }
+};
+
+template <typename Point>
+struct assign<point_tag, Point, 3>
+{
+    typedef typename coordinate_type<Point>::type coordinate_type;
+
+    template <typename T>
+    static inline void apply(Point& point, T const& c1, T const& c2, T const& c3)
+    {
+        set<0>(point, boost::numeric_cast<coordinate_type>(c1));
+        set<1>(point, boost::numeric_cast<coordinate_type>(c2));
+        set<2>(point, boost::numeric_cast<coordinate_type>(c3));
+    }
+};
+
+template <typename Box>
+struct assign<box_tag, Box, 2>
+{
+    typedef typename coordinate_type<Box>::type coordinate_type;
+
+    // Here we assign 4 coordinates to a box.
+    // -> Most logical is: x1,y1,x2,y2
+    // In case the user reverses x1/x2 or y1/y2, we could reverse them (THAT IS NOT IMPLEMENTED)
+
+    // Note also comment in util/assign_box_corner ->
+    //   ("Most logical is LOWER, UPPER and sub-order LEFT, RIGHT")
+    //   (That is assigning 4 points from a box. So lower-left, lower-right, upper-left, upper-right)
+    template <typename T>
+    static inline void apply(Box& box,
+                T const& x1, T const& y1, T const& x2, T const& y2)
+    {
+        set<min_corner, 0>(box, boost::numeric_cast<coordinate_type>(x1));
+        set<min_corner, 1>(box, boost::numeric_cast<coordinate_type>(y1));
+        set<max_corner, 0>(box, boost::numeric_cast<coordinate_type>(x2));
+        set<max_corner, 1>(box, boost::numeric_cast<coordinate_type>(y2));
+    }
+};
+
+
+
+template <typename GeometryTag, typename Geometry>
+struct assign_zero {};
+
+
+template <typename Point>
+struct assign_zero<point_tag, Point>
+    : detail::assign::assign_zero_point<Point>
+{};
+
+template <typename Box>
+struct assign_zero<box_tag, Box>
+    : detail::assign::assign_zero_box<Box>
+{};
+
+
+template <typename GeometryTag, typename Geometry>
+struct assign_inverse {};
+
+template <typename Box>
+struct assign_inverse<box_tag, Box>
+    : detail::assign::assign_inverse_box<Box>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+    \brief assign two values to a 2D point
+    \ingroup access
+ */
+template <typename Geometry, typename Type>
+inline void assign(Geometry& geometry, Type const& c1, Type const& c2)
+{
+    concept::check<Geometry>();
+
+    dispatch::assign
+        <
+            typename tag<Geometry>::type,
+            Geometry,
+            ggl::dimension<Geometry>::type::value
+        >::apply(geometry, c1, c2);
+}
+
+/*!
+    \brief assign three values to a 3D point [or the center + radius to a circle]
+    \ingroup access
+ */
+template <typename Geometry, typename Type>
+inline void assign(Geometry& geometry,
+            Type const& c1, Type const& c2, Type const& c3)
+{
+    concept::check<Geometry>();
+
+    dispatch::assign
+        <
+            typename tag<Geometry>::type,
+            Geometry,
+            ggl::dimension<Geometry>::type::value
+        >::apply(geometry, c1, c2, c3);
+}
+
+/*!
+    \brief assign center + radius to a sphere [for extension]
+    \ingroup access
+ */
+template <typename Geometry, typename Type>
+inline void assign(Geometry& geometry,
+                Type const& c1, Type const& c2, Type const& c3, Type const& c4)
+{
+    concept::check<Geometry>();
+
+    dispatch::assign
+        <
+            typename tag<Geometry>::type,
+            Geometry,
+            ggl::dimension<Geometry>::type::value
+        >::apply(geometry, c1, c2, c3, c4);
+}
+
+
+/*!
+    \brief assign a range of points to a linestring, ring or polygon
+    \note The point-type of the range might be different from the point-type of the geometry
+    \ingroup access
+ */
+template <typename Geometry, typename Range>
+inline void assign(Geometry& geometry, Range const& range)
+{
+    concept::check<Geometry>();
+
+    clear(geometry);
+    ggl::append(geometry, range, -1, 0);
+}
+
+
+/*!
+    \brief assign to a box inverse infinite
+    \details The assign_inverse function initialize a 2D or 3D box with large coordinates, the
+    min corner is very large, the max corner is very small. This is a convenient starting point to
+    collect the minimum bounding box of a geometry.
+    \ingroup access
+ */
+template <typename Geometry>
+inline void assign_inverse(Geometry& geometry)
+{
+    concept::check<Geometry>();
+
+    dispatch::assign_inverse
+        <
+            typename tag<Geometry>::type,
+            Geometry
+        >::apply(geometry);
+}
+
+/*!
+    \brief assign zero values to a box, point
+    \ingroup access
+    \details The assign_zero function initializes a 2D or 3D point or box with coordinates of zero
+    \tparam Geometry the geometry type
+ */
+template <typename Geometry>
+inline void assign_zero(Geometry& geometry)
+{
+    concept::check<Geometry>();
+
+    dispatch::assign_zero
+        <
+            typename tag<Geometry>::type,
+            Geometry
+        >::apply(geometry);
+}
+
+
+/*!
+    \brief Assign the 4 points of a 2D box
+    \ingroup access
+    \note The order is crucial. Most logical is LOWER, UPPER and sub-order LEFT, RIGHT
+        so this is how it is implemented.
+*/
+template <typename Box, typename Point>
+inline void assign_box_corners(Box const& box,
+        Point& lower_left, Point& lower_right,
+        Point& upper_left, Point& upper_right)
+{
+    concept::check<const Box>();
+    concept::check<Point>();
+
+    detail::assign::assign_box_2d_corner
+            <min_corner, min_corner>(box, lower_left);
+    detail::assign::assign_box_2d_corner
+            <max_corner, min_corner>(box, lower_right);
+    detail::assign::assign_box_2d_corner
+            <min_corner, max_corner>(box, upper_left);
+    detail::assign::assign_box_2d_corner
+            <max_corner, max_corner>(box, upper_right);
+}
+
+
+
+/*!
+    \brief Assign a box or segment with the value of a point
+    \ingroup access
+    \tparam Index indicates which box-corner, min_corner (0) or max_corner (1)
+        or which point of segment (0/1)
+*/
+template <std::size_t Index, typename Geometry, typename Point>
+inline void assign_point_to_index(Point const& point, Geometry& geometry)
+{
+    concept::check<const Point>();
+    concept::check<Geometry>();
+
+    detail::assign::assign_point_to_index
+        <
+            Geometry, Point, Index, 0, dimension<Geometry>::type::value
+        >::apply(point, geometry);
+}
+
+
+/*!
+    \brief Assign a point with a point of a box or segment
+    \ingroup access
+    \tparam Index indicates which box-corner, min_corner (0) or max_corner (1)
+        or which point of segment (0/1)
+*/
+template <std::size_t Index, typename Point, typename Geometry>
+inline void assign_point_from_index(Geometry const& geometry, Point& point)
+{
+    concept::check<const Geometry>();
+    concept::check<Point>();
+
+    detail::assign::assign_point_from_index
+        <
+            Geometry, Point, Index, 0, dimension<Geometry>::type::value
+        >::apply(geometry, point);
+}
+
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_ASSIGN_HPP
Added: sandbox/ggl/formal_review/boost/ggl/algorithms/centroid.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/algorithms/centroid.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,468 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Copyright (c) 2009 Mateusz Loskot <mateusz_at_[hidden]>
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_CENTROID_HPP
+#define GGL_ALGORITHMS_CENTROID_HPP
+
+#include <cstddef>
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/algorithms/distance.hpp>
+#include <ggl/core/cs.hpp>
+#include <ggl/core/coordinate_dimension.hpp>
+#include <ggl/core/exception.hpp>
+#include <ggl/core/exterior_ring.hpp>
+#include <ggl/core/interior_rings.hpp>
+#include <ggl/geometries/concepts/check.hpp>
+#include <ggl/iterators/segment_iterator.hpp>
+#include <ggl/strategies/centroid.hpp>
+#include <ggl/strategies/concepts/centroid_concept.hpp>
+#include <ggl/util/copy.hpp>
+#include <ggl/util/for_each_coordinate.hpp>
+
+
+/*!
+\defgroup centroid centroid: calculate centroid (center of gravity) of a geometry
+\par Source descriptions:
+- OGC description: The mathematical centroid for this Surface as a Point. The
+    result is not guaranteed to be on this Surface.
+- From Wikipedia: Informally, it is the "average" of all points
+\see http://en.wikipedia.org/wiki/Centroid
+\note Polygon should be closed, and can be orientated either way
+\note The "centroid" functions are taking a non const reference to the centroid.
+    The "make_centroid" functions return the centroid, the type has to be
+    specified.
+\note Both of them have an overloaded version where
+    a centroid calculation strategy can be specified
+\exception centroid_exception if calculation is not successful,
+    e.g. because polygon didn't contain points
+
+\par Example:
+Example showing centroid calculation
+\dontinclude doxygen_1.cpp
+\skip example_centroid_polygon
+\line {
+\until }
+
+\par Performance
+2776 * 1000 centroid calculations are done in 0.16 seconds
+(http://trac.osgeo.org/ggl/wiki/Performance#Centroid1)
+
+\par Geometries:
+- RING: \image html centroid_ring.png
+- BOX: the centroid of a 2D or 3D box is the center of the box
+- POLYGON \image html centroid_polygon.png
+- POINT: the point is the centroid
+- LINESTRING: the average of the centers of its segments
+- MULTIPOINT: the average of the points
+*/
+
+namespace ggl
+{
+
+class centroid_exception : public ggl::exception
+{
+public:
+
+    inline centroid_exception() {}
+
+    virtual char const* what() const throw()
+    {
+        return "GGL Centroid calculation exception";
+    }
+};
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace centroid {
+
+template<typename Point, typename PointCentroid, typename Strategy>
+struct centroid_point
+{
+    static inline void apply(Point const& point, PointCentroid& centroid,
+            Strategy const&)
+    {
+        copy_coordinates(point, centroid);
+    }
+};
+
+template
+<
+    typename Box,
+    typename Point,
+    std::size_t Dimension,
+    std::size_t DimensionCount
+>
+struct centroid_box_calculator
+{
+    typedef typename select_coordinate_type
+        <
+            Box, Point
+        >::type coordinate_type;
+    static inline void apply(Box const& box, Point& centroid)
+    {
+        coordinate_type const c1 = get<min_corner, Dimension>(box);
+        coordinate_type const c2 = get<max_corner, Dimension>(box);
+        coordinate_type m = c1 + c2;
+        m /= 2.0;
+
+        set<Dimension>(centroid, m);
+
+        centroid_box_calculator
+            <
+                Box, Point,
+                Dimension + 1, DimensionCount
+            >::apply(box, centroid);
+    }
+};
+
+template<typename Box, typename Point, std::size_t DimensionCount>
+struct centroid_box_calculator<Box, Point, DimensionCount, DimensionCount>
+{
+    static inline void apply(Box const& , Point& )
+    {
+    }
+};
+
+template<typename Box, typename Point, typename Strategy>
+struct centroid_box
+{
+    static inline void apply(Box const& box, Point& centroid,
+            Strategy const&)
+    {
+        centroid_box_calculator
+            <
+                Box, Point,
+                0, dimension<Box>::type::value
+            >::apply(box, centroid);
+    }
+};
+
+// There is one thing where centroid is different from e.g. within.
+// If the ring has only one point, it might make sense that
+// that point is the centroid.
+template<typename Point, typename Range>
+inline bool range_ok(Range const& range, Point& centroid)
+{
+    std::size_t const n = boost::size(range);
+    if (n > 1)
+    {
+        return true;
+    }
+    else if (n <= 0)
+    {
+#if defined(CENTROID_WITH_CATCH)
+        throw centroid_exception();
+#endif
+        return false;
+    }
+    else // if (n == 1)
+    {
+        // Take over the first point in a "coordinate neutral way"
+        copy_coordinates(range.front(), centroid);
+        return false;
+    }
+    return true;
+}
+
+
+/*!
+    \brief Calculate the centroid of a ring.
+*/
+template<typename Ring, typename Strategy>
+struct centroid_ring_state
+{
+    static inline void apply(Ring const& ring,
+            Strategy const& strategy, typename Strategy::state_type& state)
+    {
+        typedef typename boost::range_const_iterator<Ring>::type iterator_type;
+        iterator_type it = boost::begin(ring);
+        for (iterator_type previous = it++;
+            it != boost::end(ring);
+            previous = it++)
+        {
+            Strategy::apply(*previous, *it, state);
+        }
+
+        /* using segment_iterator: nice, well looking, but much slower...
+            normal iterator: 0.156 s
+            segment iterator: 1.985 s...
+        typedef segment_iterator
+            <
+                typename boost::range_const_iterator<Ring>::type,
+                typename point_type<Ring>::type
+            > iterator_type;
+
+        iterator_type it(boost::begin(ring), boost::end(ring));
+        iterator_type end(boost::end(ring));
+        for(; it != end; ++it)
+        {
+            Strategy::apply(it->first, it->second, state);
+        }
+        */
+    }
+};
+
+template<typename Ring, typename Point, typename Strategy>
+struct centroid_ring
+{
+    static inline void apply(Ring const& ring, Point& centroid,
+            Strategy const& strategy)
+    {
+        if (range_ok(ring, centroid))
+        {
+            typename Strategy::state_type state;
+            centroid_ring_state
+                <
+                    Ring,
+                    Strategy
+                >::apply(ring, strategy, state);
+            Strategy::result(state, centroid);
+        }
+    }
+};
+
+/*!
+    \brief Centroid of a linestring.
+*/
+template<typename Linestring, typename Point, typename Strategy>
+struct centroid_linestring
+{
+    static inline void apply(Linestring const& line, Point& centroid,
+            Strategy const& strategy)
+    {
+        // First version, should
+        // - be moved to a strategy
+        // - be made dim-agnostic
+
+        typedef typename point_type<Linestring>::type point_type;
+        typedef typename boost::range_const_iterator<Linestring>::type point_iterator_type;
+        typedef segment_iterator<point_iterator_type, point_type> segment_iterator;
+
+        double length = double();
+        std::pair<double, double> average_sum;
+
+        segment_iterator it(boost::begin(line), boost::end(line));
+        segment_iterator end(boost::end(line));
+        while (it != end)
+        {
+            double const d = ggl::distance(it->first, it->second);
+            length += d;
+
+            double const mx = (get<0>(it->first) + get<0>(it->second)) / 2;
+            double const my = (get<1>(it->first) + get<1>(it->second)) / 2;
+            average_sum.first += d * mx;
+            average_sum.second += d * my;
+            ++it;
+        }
+
+        set<0>(centroid, average_sum.first / length );
+        set<1>(centroid, average_sum.second / length );
+    }
+};
+
+/*!
+    \brief Centroid of a polygon.
+    \note Because outer ring is clockwise, inners are counter clockwise,
+    triangle approach is OK and works for polygons with rings.
+*/
+template<typename Polygon, typename Strategy>
+struct centroid_polygon_state
+{
+    static inline void apply(Polygon const& poly,
+            Strategy const& strategy, typename Strategy::state_type& state)
+    {
+        typedef centroid_ring_state
+            <
+                typename ring_type<Polygon>::type,
+                Strategy
+            > per_ring;
+
+        per_ring::apply(exterior_ring(poly), strategy, state);
+
+        for (typename boost::range_const_iterator
+                <
+                    typename interior_type<Polygon>::type
+                >::type it = boost::begin(interior_rings(poly));
+             it != boost::end(interior_rings(poly));
+             ++it)
+        {
+            per_ring::apply(*it, strategy, state);
+        }
+    }
+};
+
+template<typename Polygon, typename Point, typename Strategy>
+struct centroid_polygon
+{
+    static inline void apply(Polygon const& poly, Point& centroid,
+            Strategy const& strategy)
+    {
+        if (range_ok(exterior_ring(poly), centroid))
+        {
+            typename Strategy::state_type state;
+            centroid_polygon_state
+                <
+                    Polygon,
+                    Strategy
+                >::apply(poly, strategy, state);
+            Strategy::result(state, centroid);
+        }
+    }
+};
+
+
+}} // namespace detail::centroid
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+    typename Tag,
+    typename Geometry,
+    typename Point,
+    typename Strategy
+>
+struct centroid {};
+
+template
+<
+    typename Geometry,
+    typename Point,
+    typename Strategy
+>
+struct centroid<point_tag, Geometry, Point, Strategy>
+    : detail::centroid::centroid_point<Geometry, Point, Strategy>
+{};
+
+template
+<
+    typename Box,
+    typename Point,
+    typename Strategy
+>
+struct centroid<box_tag, Box, Point, Strategy>
+    : detail::centroid::centroid_box<Box, Point, Strategy>
+{};
+
+template <typename Ring, typename Point, typename Strategy>
+struct centroid<ring_tag, Ring, Point, Strategy>
+    : detail::centroid::centroid_ring<Ring, Point, Strategy>
+{};
+
+template <typename Linestring, typename Point, typename Strategy>
+struct centroid<linestring_tag, Linestring, Point, Strategy>
+    : detail::centroid::centroid_linestring<Linestring, Point, Strategy>
+ {};
+
+template <typename Polygon, typename Point, typename Strategy>
+struct centroid<polygon_tag, Polygon, Point, Strategy>
+    : detail::centroid::centroid_polygon<Polygon, Point, Strategy>
+ {};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+    \brief Calculate centroid using a specified strategy
+    \ingroup centroid
+    \param geometry the geometry to calculate centroid from
+    \param c reference to point which will contain the centroid
+    \param strategy Calculation strategy for centroid
+ */
+template<typename Geometry, typename Point, typename Strategy>
+inline void centroid(Geometry const& geometry, Point& c,
+        Strategy const& strategy)
+{
+    //BOOST_CONCEPT_ASSERT( (ggl::concept::CentroidStrategy<Strategy>) );
+
+    concept::check_concepts_and_equal_dimensions<Point, const Geometry>();
+
+    typedef typename point_type<Geometry>::type point_type;
+
+    // Call dispatch apply method. That one returns true if centroid
+    // should be taken from state.
+    dispatch::centroid
+        <
+            typename tag<Geometry>::type,
+            Geometry,
+            Point,
+            Strategy
+        >::apply(geometry, c, strategy);
+}
+
+
+/*!
+    \brief Calculate centroid
+    \ingroup centroid
+    \param geometry a geometry (e.g. closed ring or polygon)
+    \param c reference to point which will contain the centroid
+ */
+template<typename Geometry, typename Point>
+inline void centroid(Geometry const& geometry, Point& c)
+{
+    concept::check_concepts_and_equal_dimensions<Point, const Geometry>();
+
+    typedef typename strategy_centroid
+        <
+            typename cs_tag<Geometry>::type,
+            typename tag<Geometry>::type,
+            dimension<Geometry>::type::value,
+            Point,
+            Geometry
+        >::type strategy_type;
+
+    centroid(geometry, c, strategy_type());
+}
+
+
+/*!
+    \brief Calculate and return centroid
+    \ingroup centroid
+    \param geometry the geometry to calculate centroid from
+    \return the centroid
+ */
+template<typename Point, typename Geometry>
+inline Point make_centroid(Geometry const& geometry)
+{
+    concept::check_concepts_and_equal_dimensions<Point, const Geometry>();
+
+    Point c;
+    centroid(geometry, c);
+    return c;
+}
+
+/*!
+    \brief Calculate and return centroid, using a specified strategy
+    \ingroup centroid
+    \param geometry the geometry to calculate centroid from
+    \param strategy Calculation strategy for centroid
+    \return the centroid
+ */
+template<typename Point, typename Geometry, typename Strategy>
+inline Point make_centroid(Geometry const& geometry, Strategy const& strategy)
+{
+    //BOOST_CONCEPT_ASSERT( (ggl::concept::CentroidStrategy<Strategy>) );
+
+    concept::check_concepts_and_equal_dimensions<Point, const Geometry>();
+
+    Point c;
+    centroid(geometry, c, strategy);
+    return c;
+}
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_CENTROID_HPP
Added: sandbox/ggl/formal_review/boost/ggl/algorithms/clear.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/algorithms/clear.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,141 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_CLEAR_HPP
+#define GGL_ALGORITHMS_CLEAR_HPP
+
+#include <boost/type_traits/remove_const.hpp>
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/exterior_ring.hpp>
+#include <ggl/core/interior_rings.hpp>
+
+#include <ggl/geometries/concepts/check.hpp>
+
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace clear {
+
+template <typename Geometry>
+struct use_std_clear
+{
+    static inline void apply(Geometry& geometry)
+    {
+        geometry.clear();
+    }
+};
+
+template <typename Geometry>
+struct use_traits_clear
+{
+    static inline void apply(Geometry& geometry)
+    {
+        traits::clear<Geometry>::apply(geometry);
+    }
+};
+
+template <typename Polygon>
+struct polygon_clear
+{
+    static inline void apply(Polygon& polygon)
+    {
+        interior_rings(polygon).clear();
+        exterior_ring(polygon).clear();
+    }
+};
+
+template <typename Geometry>
+struct no_action
+{
+    static inline void apply(Geometry& geometry)
+    {
+    }
+};
+
+}} // namespace detail::clear
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Tag, bool UseStd, typename Geometry>
+struct clear
+{};
+
+// True (default for all geometry types, unless otherwise implemented in traits)
+// uses std::clear
+template <typename Tag, typename Geometry>
+struct clear<Tag, true, Geometry>
+    : detail::clear::use_std_clear<Geometry>
+{};
+
+// If any geometry specializes use_std<Geometry> to false, specialize to use the traits clear.
+template <typename Tag, typename Geometry>
+struct clear<Tag, false, Geometry>
+    : detail::clear::use_traits_clear<Geometry>
+{};
+
+// Point/box/segment do not have clear. So specialize to do nothing.
+template <typename Geometry>
+struct clear<point_tag, true, Geometry>
+    : detail::clear::no_action<Geometry>
+{};
+
+template <typename Geometry>
+struct clear<box_tag, true, Geometry>
+    : detail::clear::no_action<Geometry>
+{};
+
+template <typename Geometry>
+struct clear<segment_tag, true, Geometry>
+    : detail::clear::no_action<Geometry>
+{};
+
+
+
+
+// Polygon can (indirectly) use std for clear
+template <typename Polygon>
+struct clear<polygon_tag, true, Polygon>
+    : detail::clear::polygon_clear<Polygon>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+    \brief Clears a linestring, linear ring or polygon (exterior+interiors) or multi*
+    \details Generic function to clear a geometry
+    \ingroup access
+    \note points and boxes cannot be cleared, instead they can be set to zero by "assign_zero"
+*/
+template <typename Geometry>
+inline void clear(Geometry& geometry)
+{
+    concept::check<Geometry>();
+
+    dispatch::clear
+        <
+            typename tag<Geometry>::type,
+            traits::use_std
+                <
+                    typename boost::remove_const<Geometry>::type
+                >::value,
+            Geometry
+        >::apply(geometry);
+}
+
+}  // namespace ggl
+
+#endif // GGL_ALGORITHMS_CLEAR_HPP
Added: sandbox/ggl/formal_review/boost/ggl/algorithms/combine.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/algorithms/combine.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,321 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_COMBINE_HPP
+#define GGL_ALGORITHMS_COMBINE_HPP
+
+#include <cstddef>
+
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <ggl/core/coordinate_dimension.hpp>
+#include <ggl/geometries/concepts/check.hpp>
+
+#include <ggl/util/select_coordinate_type.hpp>
+
+#include <ggl/strategies/compare.hpp>
+#include <ggl/policies/compare.hpp>
+
+
+/*!
+\defgroup combine combine: add a geometry to a bounding box
+\par Geometries:
+- \b box + \b box -> \b box: the box will be combined with the other box
+    \image html combine_box_box.png
+    \note Also if the input box is incorrect, the box will correctly updated
+- \b box + \b point -> \b box: the box will combined with the point
+    \image html combine_box_point.png
+- \b box + \b segment -> \b box
+*/
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace combine {
+
+
+template
+<
+    typename Box, typename Point,
+    typename StrategyLess, typename StrategyGreater,
+    std::size_t Dimension, std::size_t DimensionCount
+>
+struct point_loop
+{
+    typedef typename strategy::compare::detail::select_strategy
+        <
+            StrategyLess, 1, Point, Dimension
+        >::type less_type;
+
+    typedef typename strategy::compare::detail::select_strategy
+        <
+            StrategyGreater, -1, Point, Dimension
+        >::type greater_type;
+
+    typedef typename select_coordinate_type<Point, Box>::type coordinate_type;
+
+    static inline void apply(Box& box, Point const& source)
+    {
+        less_type less;
+        greater_type greater;
+
+        coordinate_type const coord = get<Dimension>(source);
+
+        if (less(coord, get<min_corner, Dimension>(box)))
+        {
+            set<min_corner, Dimension>(box, coord);
+        }
+
+        if (greater(coord, get<max_corner, Dimension>(box)))
+        {
+            set<max_corner, Dimension>(box, coord);
+        }
+
+        point_loop
+            <
+                Box, Point,
+                StrategyLess, StrategyGreater,
+                Dimension + 1, DimensionCount
+            >::apply(box, source);
+    }
+};
+
+
+template
+<
+    typename Box, typename Point,
+    typename StrategyLess, typename StrategyGreater,
+    std::size_t DimensionCount
+>
+struct point_loop
+    <
+        Box, Point,
+        StrategyLess, StrategyGreater,
+        DimensionCount, DimensionCount
+    >
+{
+    static inline void apply(Box&, Point const&) {}
+};
+
+
+template
+<
+    typename Box, typename Geometry,
+    typename StrategyLess, typename StrategyGreater,
+    std::size_t Index,
+    std::size_t Dimension, std::size_t DimensionCount
+>
+struct indexed_loop
+{
+    typedef typename strategy::compare::detail::select_strategy
+        <
+            StrategyLess, 1, Box, Dimension
+        >::type less_type;
+
+    typedef typename strategy::compare::detail::select_strategy
+        <
+            StrategyGreater, -1, Box, Dimension
+        >::type greater_type;
+
+    typedef typename select_coordinate_type
+            <
+                Box,
+                Geometry
+            >::type coordinate_type;
+
+
+    static inline void apply(Box& box, Geometry const& source)
+    {
+        less_type less;
+        greater_type greater;
+
+        coordinate_type const coord = get<Index, Dimension>(source);
+
+        if (less(coord, get<min_corner, Dimension>(box)))
+        {
+            set<min_corner, Dimension>(box, coord);
+        }
+
+        if (greater(coord, get<max_corner, Dimension>(box)))
+        {
+            set<max_corner, Dimension>(box, coord);
+        }
+
+        indexed_loop
+            <
+                Box, Geometry,
+                StrategyLess, StrategyGreater,
+                Index, Dimension + 1, DimensionCount
+            >::apply(box, source);
+    }
+};
+
+
+template
+<
+    typename Box, typename Geometry,
+    typename StrategyLess, typename StrategyGreater,
+    std::size_t Index, std::size_t DimensionCount
+>
+struct indexed_loop
+    <
+        Box, Geometry,
+        StrategyLess, StrategyGreater,
+        Index, DimensionCount, DimensionCount
+    >
+{
+    static inline void apply(Box&, Geometry const&) {}
+};
+
+
+
+// Changes a box such that the other box is also contained by the box
+template
+<
+    typename Box, typename Geometry,
+    typename StrategyLess, typename StrategyGreater
+>
+struct combine_indexed
+{
+    static inline void apply(Box& box, Geometry const& geometry)
+    {
+        indexed_loop
+            <
+                Box, Geometry,
+                StrategyLess, StrategyGreater,
+                0, 0, dimension<Geometry>::type::value
+            >::apply(box, geometry);
+
+        indexed_loop
+            <
+                Box, Geometry,
+                StrategyLess, StrategyGreater,
+                1, 0, dimension<Geometry>::type::value
+            >::apply(box, geometry);
+    }
+};
+
+}} // namespace detail::combine
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+    typename Tag,
+    typename BoxOut, typename Geometry,
+    typename StrategyLess, typename StrategyGreater
+>
+struct combine
+{};
+
+
+// Box + point -> new box containing also point
+template
+<
+    typename BoxOut, typename Point,
+    typename StrategyLess, typename StrategyGreater
+>
+struct combine<point_tag, BoxOut, Point, StrategyLess, StrategyGreater>
+    : detail::combine::point_loop
+        <
+            BoxOut, Point,
+            StrategyLess, StrategyGreater,
+            0, dimension<Point>::type::value
+        >
+{};
+
+
+// Box + box -> new box containing two input boxes
+template
+<
+    typename BoxOut, typename BoxIn,
+    typename StrategyLess, typename StrategyGreater
+>
+struct combine<box_tag, BoxOut, BoxIn, StrategyLess, StrategyGreater>
+    : detail::combine::combine_indexed
+        <BoxOut, BoxIn, StrategyLess, StrategyGreater>
+{};
+
+template
+<
+    typename Box, typename Segment,
+    typename StrategyLess, typename StrategyGreater
+>
+struct combine<segment_tag, Box, Segment, StrategyLess, StrategyGreater>
+    : detail::combine::combine_indexed
+        <Box, Segment, StrategyLess, StrategyGreater>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/***
+*!
+    \brief Combines a box with another geometry (box, point)
+    \ingroup combine
+    \tparam Box type of the box
+    \tparam Geometry of second geometry, to be combined with the box
+    \param box box to combine another geometry with, might be changed
+    \param geometry other geometry
+    \param strategy_less
+    \param strategy_greater
+    \note Strategy is currently ignored
+    \todo Handle strategy
+ *
+template
+<
+    typename Box, typename Geometry,
+    typename StrategyLess, typename StrategyGreater
+>
+inline void combine(Box& box, Geometry const& geometry,
+            StrategyLess const& strategy_less,
+            StrategyGreater const& strategy_greater)
+{
+    concept::check_concepts_and_equal_dimensions<Box, const Geometry>();
+
+    dispatch::combine
+        <
+            typename tag<Geometry>::type,
+            Box,
+            Geometry,
+            StrategyLess, StrategyGreater
+        >::apply(box, geometry);
+}
+***/
+
+
+/*!
+    \brief Combines a box with another geometry (box, point)
+    \ingroup combine
+    \tparam Box type of the box
+    \tparam Geometry of second geometry, to be combined with the box
+    \param box box to combine another geometry with, might be changed
+    \param geometry other geometry
+ */
+template <typename Box, typename Geometry>
+inline void combine(Box& box, Geometry const& geometry)
+{
+    concept::check_concepts_and_equal_dimensions<Box, const Geometry>();
+
+    dispatch::combine
+        <
+            typename tag<Geometry>::type,
+            Box, Geometry,
+            strategy::compare::default_strategy,
+            strategy::compare::default_strategy
+        >::apply(box, geometry);
+}
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_COMBINE_HPP
Added: sandbox/ggl/formal_review/boost/ggl/algorithms/convert.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/algorithms/convert.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,252 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_CONVERT_HPP
+#define GGL_ALGORITHMS_CONVERT_HPP
+
+#include <cstddef>
+
+#include <boost/numeric/conversion/cast.hpp>
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/algorithms/append.hpp>
+#include <ggl/algorithms/assign.hpp>
+#include <ggl/algorithms/for_each.hpp>
+
+#include <ggl/core/cs.hpp>
+#include <ggl/geometries/concepts/check.hpp>
+
+
+/*!
+\defgroup convert convert: convert geometries from one type to another
+\details Convert from one geometry type to another type,
+    for example from BOX to POLYGON
+\par Geometries:
+- \b point to \b box -> a zero-area box of a point
+- \b box to \b ring -> a rectangular ring
+- \b box to \b polygon -> a rectangular polygon
+- \b ring to \b polygon -> polygon with an exterior ring (the input ring)
+- \b polygon to \b ring -> ring, interior rings (if any) are ignored
+*/
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace convert {
+
+template
+<
+    typename Point,
+    typename Box,
+    std::size_t Index,
+    std::size_t Dimension,
+    std::size_t DimensionCount
+>
+struct point_to_box
+{
+    static inline void apply(Point const& point, Box& box)
+    {
+        typedef typename coordinate_type<Box>::type coordinate_type;
+
+        set<Index, Dimension>(box,
+                boost::numeric_cast<coordinate_type>(get<Dimension>(point)));
+        point_to_box
+            <
+                Point, Box,
+                Index, Dimension + 1, DimensionCount
+            >::apply(point, box);
+    }
+};
+
+
+template
+<
+    typename Point,
+    typename Box,
+    std::size_t Index,
+    std::size_t DimensionCount
+>
+struct point_to_box<Point, Box, Index, DimensionCount, DimensionCount>
+{
+    static inline void apply(Point const& point, Box& box)
+    {}
+};
+
+
+}} // namespace detail::convert
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+    typename Tag1, typename Tag2,
+    std::size_t Dimensions,
+    typename Geometry1, typename Geometry2
+>
+struct convert
+{
+};
+
+
+template
+<
+    typename Tag,
+    std::size_t Dimensions,
+    typename Geometry1, typename Geometry2
+>
+struct convert<Tag, Tag, Dimensions, Geometry1, Geometry2>
+{
+    // Same geometry type -> copy coordinates from G1 to G2
+    // Actually: we try now to just copy it
+    static inline void apply(Geometry1 const& source, Geometry2& destination)
+    {
+        destination = source;
+    }
+};
+
+
+template <typename Tag, std::size_t Dimensions, typename Geometry>
+struct convert<Tag, Tag, Dimensions, Geometry, Geometry>
+{
+    // Same geometry -> can be copied (if copyable)
+    static inline void apply(Geometry const& source, Geometry& destination)
+    {
+        destination = source;
+    }
+};
+
+
+// Partial specializations
+template <typename Box, typename Ring>
+struct convert<box_tag, ring_tag, 2, Box, Ring>
+{
+    static inline void apply(Box const& box, Ring& ring)
+    {
+        // go from box to ring -> add coordinates in correct order
+        ring.clear();
+        typename point_type<Box>::type point;
+
+        ggl::assign(point, get<min_corner, 0>(box), get<min_corner, 1>(box));
+        ggl::append(ring, point);
+
+        ggl::assign(point, get<min_corner, 0>(box), get<max_corner, 1>(box));
+        ggl::append(ring, point);
+
+        ggl::assign(point, get<max_corner, 0>(box), get<max_corner, 1>(box));
+        ggl::append(ring, point);
+
+        ggl::assign(point, get<max_corner, 0>(box), get<min_corner, 1>(box));
+        ggl::append(ring, point);
+
+        ggl::assign(point, get<min_corner, 0>(box), get<min_corner, 1>(box));
+        ggl::append(ring, point);
+    }
+};
+
+
+template <typename Box, typename Polygon>
+struct convert<box_tag, polygon_tag, 2, Box, Polygon>
+{
+    static inline void apply(Box const& box, Polygon& polygon)
+    {
+        typedef typename ring_type<Polygon>::type ring_type;
+
+        convert
+            <
+                box_tag, ring_tag,
+                2, Box, ring_type
+            >::apply(box, exterior_ring(polygon));
+    }
+};
+
+
+template <typename Point, std::size_t Dimensions, typename Box>
+struct convert<point_tag, box_tag, Dimensions, Point, Box>
+{
+    static inline void apply(Point const& point, Box& box)
+    {
+        detail::convert::point_to_box
+            <
+                Point, Box, min_corner, 0, Dimensions
+            >::apply(point, box);
+        detail::convert::point_to_box
+            <
+                Point, Box, max_corner, 0, Dimensions
+            >::apply(point, box);
+    }
+};
+
+
+template <typename Ring, typename Polygon>
+struct convert<ring_tag, polygon_tag, 2, Ring, Polygon>
+{
+    static inline void apply(Ring const& ring, Polygon& polygon)
+    {
+        typedef typename ring_type<Polygon>::type ring_type;
+        convert
+            <
+                ring_tag, ring_tag, 2,
+                Ring, ring_type
+            >::apply(ring, exterior_ring(polygon));
+    }
+};
+
+
+template <typename Polygon, typename Ring>
+struct convert<polygon_tag, ring_tag, 2, Polygon, Ring>
+{
+    static inline void apply(Polygon const& polygon, Ring& ring)
+    {
+        typedef typename ring_type<Polygon>::type ring_type;
+
+        convert
+            <
+                ring_tag, ring_tag, 2,
+                ring_type, Ring
+            >::apply(exterior_ring(polygon), ring);
+    }
+};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+/*!
+    \brief Converts one geometry to another geometry
+    \details The convert algorithm converts one geometry, e.g. a BOX, to another geometry, e.g. a RING. This only
+    if it is possible and applicable.
+    \ingroup convert
+    \tparam Geometry1 first geometry type
+    \tparam Geometry2 second geometry type
+    \param geometry1 first geometry (source)
+    \param geometry2 second geometry (target)
+ */
+template <typename Geometry1, typename Geometry2>
+inline void convert(Geometry1 const& geometry1, Geometry2& geometry2)
+{
+    concept::check_concepts_and_equal_dimensions<const Geometry1, Geometry2>();
+
+    dispatch::convert
+        <
+            typename tag<Geometry1>::type,
+            typename tag<Geometry2>::type,
+            dimension<Geometry1>::type::value,
+            Geometry1,
+            Geometry2
+        >::apply(geometry1, geometry2);
+}
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_CONVERT_HPP
Added: sandbox/ggl/formal_review/boost/ggl/algorithms/convex_hull.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/algorithms/convex_hull.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,279 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_CONVEX_HULL_HPP
+#define GGL_ALGORITHMS_CONVEX_HULL_HPP
+
+
+#include <boost/type_traits/remove_const.hpp>
+
+#include <ggl/core/cs.hpp>
+#include <ggl/core/is_multi.hpp>
+#include <ggl/core/point_order.hpp>
+#include <ggl/core/exterior_ring.hpp>
+
+#include <ggl/geometries/concepts/check.hpp>
+
+#include <ggl/iterators/range_type.hpp>
+
+#include <ggl/strategies/convex_hull.hpp>
+#include <ggl/strategies/concepts/convex_hull_concept.hpp>
+
+#include <ggl/util/as_range.hpp>
+
+
+/*!
+\defgroup convex_hull convex hull: calculate the convex hull of a geometry
+\par Source descriptions:
+- OGC description: Returns a geometric object that represents the convex hull of
+    this geometric object. Convex hulls, being dependent on straight lines, can
+    be accurately represented in linear interpolations
+    for any geometry restricted to linear interpolations.
+\see http://en.wikipedia.org/wiki/Convex_hull
+
+\par Performance
+2776 counties of US are "hulled" in 0.9 seconds
+(http://trac.osgeo.org/ggl/wiki/Performance#Convexhull1)
+
+\note The convex hull is always a ring, holes are not possible. Therefore it is
+    can also be used in combination with an output iterator.
+
+\par Geometries supported:
+In the images below the convex hull is painted in red.
+
+- \b point: will not compile
+
+- \b linestring:
+
+- \b polygon: will deliver a polygon without holes
+    \image html svg_convex_hull_country.png
+
+- \b multi_point:
+    \image html svg_convex_hull_cities.png
+
+- \b multi_linestring:
+
+- \b multi_polygon:
+
+\par Output geometries supported:
+
+- \b polygon
+
+- \b ring
+
+- inserter version (with output iterator) can output to any array supporting
+    points of same type as the input geometry type
+
+*/
+namespace ggl {
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace convex_hull {
+
+template
+<
+    typename Geometry,
+    order_selector Order,
+    typename Strategy
+>
+struct hull_inserter
+{
+
+    // Member template function, to avoid inconvenient declaration
+    // of output-iterator-type, from hull_to_geometry
+    template <typename OutputIterator>
+    static inline OutputIterator apply(Geometry const& geometry,
+            OutputIterator out, Strategy const& strategy)
+    {
+        typename Strategy::state_type state;
+
+        strategy.apply(geometry, state);
+        strategy.result(state, out, Order == clockwise);
+        return out;
+    }
+};
+
+template
+<
+    typename Geometry,
+    typename OutputGeometry,
+    typename Strategy
+>
+struct hull_to_geometry
+{
+    static inline void apply(Geometry const& geometry, OutputGeometry& out,
+            Strategy const& strategy)
+    {
+        hull_inserter
+            <
+                Geometry,
+                ggl::point_order<OutputGeometry>::value,
+                Strategy
+            >::apply(geometry,
+                std::back_inserter(
+                    // Handle both ring and polygon the same:
+                    ggl::as_range
+                        <
+                            typename ggl::range_type<OutputGeometry>::type
+                        >(out)), strategy);
+    }
+};
+
+
+}} // namespace detail::convex_hull
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template
+<
+    typename Tag1,
+    bool IsMulti,
+    typename Geometry,
+    typename Output,
+    typename Strategy
+>
+struct convex_hull
+    : detail::convex_hull::hull_to_geometry<Geometry, Output, Strategy>
+{};
+
+
+template
+<
+    typename GeometryTag,
+    order_selector Order,
+    bool IsMulti,
+    typename GeometryIn, typename Strategy
+ >
+struct convex_hull_inserter
+    : detail::convex_hull::hull_inserter<GeometryIn, Order, Strategy>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+template<typename Geometry1, typename Geometry2, typename Strategy>
+inline void convex_hull(Geometry1 const& geometry,
+            Geometry2& out, Strategy const& strategy)
+{
+    concept::check_concepts_and_equal_dimensions
+        <
+            const Geometry1,
+            Geometry2
+        >();
+
+    BOOST_CONCEPT_ASSERT( (ggl::concept::ConvexHullStrategy<Strategy>) );
+
+
+    dispatch::convex_hull
+        <
+            typename tag<Geometry1>::type,
+            is_multi<Geometry1>::type::value,
+            Geometry1,
+            Geometry2,
+            Strategy
+        >::apply(geometry, out, strategy);
+}
+
+
+/*!
+    \brief Calculate the convex hull of a geometry
+    \ingroup convex_hull
+    \tparam Geometry1 the input geometry type
+    \tparam Geometry2: the output geometry type
+    \param geometry the geometry to calculate convex hull from
+    \param out a geometry receiving points of the convex hull
+ */
+template<typename Geometry1, typename Geometry2>
+inline void convex_hull(Geometry1 const& geometry,
+            Geometry2& out)
+{
+    concept::check_concepts_and_equal_dimensions
+        <
+            const Geometry1,
+            Geometry2
+        >();
+
+    //typedef typename range_type<Geometry1>::type range_type;
+    typedef typename point_type<Geometry2>::type point_type;
+
+    typedef typename strategy_convex_hull
+        <
+            typename cs_tag<point_type>::type,
+            Geometry1,
+            point_type
+        >::type strategy_type;
+
+    convex_hull(geometry, out, strategy_type());
+}
+
+
+template<typename Geometry, typename OutputIterator, typename Strategy>
+inline OutputIterator convex_hull_inserter(Geometry const& geometry,
+            OutputIterator out, Strategy const& strategy)
+{
+    // Concept: output point type = point type of input geometry
+    concept::check<const Geometry>();
+    concept::check<typename point_type<Geometry>::type>();
+
+    BOOST_CONCEPT_ASSERT( (ggl::concept::ConvexHullStrategy<Strategy>) );
+
+    return dispatch::convex_hull_inserter
+        <
+            typename tag<Geometry>::type,
+            ggl::point_order<Geometry>::value,
+            is_multi<Geometry>::type::value,
+            Geometry, Strategy
+        >::apply(geometry, out, strategy);
+}
+
+
+/*!
+    \brief Calculate the convex hull of a geometry, output-iterator version
+    \ingroup convex_hull
+    \tparam Geometry the input geometry type
+    \tparam OutputIterator: an output-iterator
+    \param geometry the geometry to calculate convex hull from
+    \param out an output iterator outputing points of the convex hull
+    \note This overloaded version outputs to an output iterator.
+    In this case, nothing is known about its point-type or
+        about its clockwise order. Therefore, the input point-type
+        and order are copied
+
+ */
+template<typename Geometry, typename OutputIterator>
+inline OutputIterator convex_hull_inserter(Geometry const& geometry,
+            OutputIterator out)
+{
+    // Concept: output point type = point type of input geometry
+    concept::check<const Geometry>();
+    concept::check<typename point_type<Geometry>::type>();
+
+    typedef typename range_type<Geometry>::type range_type;
+    typedef typename point_type<Geometry>::type point_type;
+
+    typedef typename strategy_convex_hull
+        <
+            typename cs_tag<point_type>::type,
+            Geometry,
+            point_type
+        >::type strategy_type;
+
+    return convex_hull_inserter(geometry, out, strategy_type());
+}
+
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_CONVEX_HULL_HPP
Added: sandbox/ggl/formal_review/boost/ggl/algorithms/correct.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/algorithms/correct.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,192 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_CORRECT_HPP
+#define GGL_ALGORITHMS_CORRECT_HPP
+
+#include <cstddef>
+#include <algorithm>
+#include <functional>
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/core/cs.hpp>
+#include <ggl/core/ring_type.hpp>
+#include <ggl/core/exterior_ring.hpp>
+#include <ggl/core/interior_rings.hpp>
+
+#include <ggl/geometries/concepts/check.hpp>
+
+#include <ggl/algorithms/area.hpp>
+#include <ggl/algorithms/disjoint.hpp>
+
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace correct {
+
+
+template <typename Box, std::size_t Dimension, std::size_t DimensionCount>
+struct correct_box_loop
+{
+    typedef typename coordinate_type<Box>::type coordinate_type;
+
+    static inline void apply(Box& box)
+    {
+        if (get<min_corner, Dimension>(box) > get<max_corner, Dimension>(box))
+        {
+            // Swap the coordinates
+            coordinate_type max_value = get<min_corner, Dimension>(box);
+            coordinate_type min_value = get<max_corner, Dimension>(box);
+            set<min_corner, Dimension>(box, min_value);
+            set<max_corner, Dimension>(box, max_value);
+        }
+
+        correct_box_loop
+            <
+                Box, Dimension + 1, DimensionCount
+            >::apply(box);
+    }
+};
+
+
+
+template <typename Box, std::size_t DimensionCount>
+struct correct_box_loop<Box, DimensionCount, DimensionCount>
+{
+    static inline void apply(Box& box)
+    {}
+
+};
+
+
+// correct an box: make min/max are correct
+template <typename Box>
+struct correct_box
+{
+
+    static inline void apply(Box& box)
+    {
+        // Currently only for Cartesian coordinates
+        // TODO: adapt using strategies
+        correct_box_loop
+            <
+                Box, 0, dimension<Box>::type::value
+            >::apply(box);
+    }
+};
+
+
+// close a linear_ring, if not closed
+template <typename Ring, typename Predicate>
+struct correct_ring
+{
+    typedef typename point_type<Ring>::type point_type;
+
+    typedef typename strategy_area
+        <
+            typename cs_tag<point_type>::type,
+            point_type
+        >::type strategy_type;
+
+    typedef detail::area::ring_area
+            <
+                Ring,
+                ggl::point_order<Ring>::value,
+                strategy_type
+            > ring_area_type;
+
+
+    static inline void apply(Ring& r)
+    {
+        // Check close-ness
+        if (boost::size(r) > 2)
+        {
+            // check if closed, if not, close it
+            if (ggl::disjoint(r.front(), r.back()))
+            {
+                r.push_back(r.front());
+            }
+        }
+        // Check area
+        Predicate predicate;
+        if (predicate(ring_area_type::apply(r, strategy_type()), 0))
+        {
+            std::reverse(boost::begin(r), boost::end(r));
+        }
+    }
+};
+
+// correct a polygon: normalizes all rings, sets outer linear_ring clockwise, sets all
+// inner rings counter clockwise
+template <typename Polygon>
+struct correct_polygon
+{
+    typedef typename ring_type<Polygon>::type ring_type;
+
+    static inline void apply(Polygon& poly)
+    {
+        correct_ring<ring_type, std::less<double> >::apply(exterior_ring(poly));
+
+        typedef typename boost::range_iterator
+            <
+                typename interior_type<Polygon>::type
+            >::type iterator_type;
+
+        for (iterator_type it = boost::begin(interior_rings(poly));
+             it != boost::end(interior_rings(poly)); ++it)
+        {
+            correct_ring<ring_type, std::greater<double> >::apply(*it);
+        }
+    }
+};
+
+
+}} // namespace detail::correct
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Tag, typename Geometry>
+struct correct {};
+
+template <typename Box>
+struct correct<box_tag, Box>
+    : detail::correct::correct_box<Box>
+{};
+
+template <typename Ring>
+struct correct<ring_tag, Ring>
+    : detail::correct::correct_ring<Ring, std::less<double> >
+{};
+
+template <typename Polygon>
+struct correct<polygon_tag, Polygon>
+    : detail::correct::correct_polygon<Polygon>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+template <typename Geometry>
+inline void correct(Geometry& geometry)
+{
+    concept::check<const Geometry>();
+
+    dispatch::correct<typename tag<Geometry>::type, Geometry>::apply(geometry);
+}
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_CORRECT_HPP
Added: sandbox/ggl/formal_review/boost/ggl/algorithms/detail/calculate_null.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/algorithms/detail/calculate_null.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,33 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_DETAIL_CALCULATE_NULL_HPP
+#define GGL_ALGORITHMS_DETAIL_CALCULATE_NULL_HPP
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+template<typename ReturnType, typename Geometry, typename Strategy>
+struct calculate_null
+{
+    static inline ReturnType apply(Geometry const& , Strategy const&)
+    {
+        return ReturnType();
+    }
+};
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_DETAIL_CALCULATE_NULL_HPP
Added: sandbox/ggl/formal_review/boost/ggl/algorithms/detail/calculate_sum.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/algorithms/detail/calculate_sum.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,51 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_DETAIL_CALCULATE_SUM_HPP
+#define GGL_ALGORITHMS_DETAIL_CALCULATE_SUM_HPP
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+
+template
+<
+    typename ReturnType,
+    typename Polygon,
+    typename Strategy,
+    typename Policy
+>
+struct calculate_polygon_sum
+{
+    static inline ReturnType apply(Polygon const& poly, Strategy const& strategy)
+    {
+        ReturnType sum = Policy::apply(exterior_ring(poly), strategy);
+
+        for (typename boost::range_const_iterator
+                <
+                    typename interior_type<Polygon>::type
+                >::type it = boost::begin(interior_rings(poly));
+             it != boost::end(interior_rings(poly));
+             ++it)
+        {
+            sum += Policy::apply(*it, strategy);
+        }
+        return sum;
+    }
+};
+
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_DETAIL_CALCULATE_SUM_HPP
Added: sandbox/ggl/formal_review/boost/ggl/algorithms/detail/disjoint.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/algorithms/detail/disjoint.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,194 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_DETAIL_DISJOINT_HPP
+#define GGL_ALGORITHMS_DETAIL_DISJOINT_HPP
+
+// Note: contrary to most files, the ggl::detail::disjoint namespace
+// is partly implemented in a separate file, to avoid circular references
+// disjoint -> get_intersection_points -> disjoint
+
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/coordinate_dimension.hpp>
+#include <ggl/core/is_multi.hpp>
+#include <ggl/core/reverse_dispatch.hpp>
+
+
+#include <ggl/util/math.hpp>
+
+
+
+namespace ggl
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace disjoint {
+
+
+template
+<
+    typename Point1, typename Point2,
+    std::size_t Dimension, std::size_t DimensionCount
+>
+struct point_point
+{
+    static inline bool apply(Point1 const& p1, Point2 const& p2)
+    {
+        if (! ggl::math::equals(get<Dimension>(p1), get<Dimension>(p2)))
+        {
+            return true;
+        }
+        return point_point
+            <
+                Point1, Point2,
+                Dimension + 1, DimensionCount
+            >::apply(p1, p2);
+    }
+};
+
+
+template <typename Point1, typename Point2, std::size_t DimensionCount>
+struct point_point<Point1, Point2, DimensionCount, DimensionCount>
+{
+    static inline bool apply(Point1 const& , Point2 const& )
+    {
+        return false;
+    }
+};
+
+
+template
+<
+    typename Point, typename Box,
+    std::size_t Dimension, std::size_t DimensionCount
+>
+struct point_box
+{
+    static inline bool apply(Point const& point, Box const& box)
+    {
+        if (get<Dimension>(point) < get<min_corner, Dimension>(box)
+            || get<Dimension>(point) > get<max_corner, Dimension>(box))
+        {
+            return true;
+        }
+        return point_box
+            <
+                Point, Box,
+                Dimension + 1, DimensionCount
+            >::apply(point, box);
+    }
+};
+
+
+template <typename Point, typename Box, std::size_t DimensionCount>
+struct point_box<Point, Box, DimensionCount, DimensionCount>
+{
+    static inline bool apply(Point const& , Box const& )
+    {
+        return false;
+    }
+};
+
+
+template
+<
+    typename Box1, typename Box2,
+    std::size_t Dimension, std::size_t DimensionCount
+>
+struct box_box
+{
+    static inline bool apply(Box1 const& box1, Box2 const& box2)
+    {
+        if (get<max_corner, Dimension>(box1) < get<min_corner, Dimension>(box2))
+        {
+            return true;
+        }
+        if (get<min_corner, Dimension>(box1) > get<max_corner, Dimension>(box2))
+        {
+            return true;
+        }
+        return box_box
+            <
+                Box1, Box2,
+                Dimension + 1, DimensionCount
+            >::apply(box1, box2);
+    }
+};
+
+
+template <typename Box1, typename Box2, std::size_t DimensionCount>
+struct box_box<Box1, Box2, DimensionCount, DimensionCount>
+{
+    static inline bool apply(Box1 const& , Box2 const& )
+    {
+        return false;
+    }
+};
+
+
+
+/*!
+    \brief Internal utility function to detect of boxes are disjoint
+    \note Is used from other algorithms, declared separately
+        to avoid circular references
+ */
+template <typename Box1, typename Box2>
+inline bool disjoint_box_box(Box1 const& box1, Box2 const& box2)
+{
+    return box_box
+        <
+            Box1, Box2,
+            0, dimension<Box1>::type::value
+        >::apply(box1, box2);
+}
+
+
+
+/*!
+    \brief Internal utility function to detect of points are disjoint
+    \note To avoid circular references
+ */
+template <typename Point1, typename Point2>
+inline bool disjoint_point_point(Point1 const& point1, Point2 const& point2)
+{
+    return point_point
+        <
+            Point1, Point2,
+            0, dimension<Point1>::type::value
+        >::apply(point1, point2);
+}
+
+
+
+
+}} // namespace detail::disjoint
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace equals {
+
+/*!
+    \brief Internal utility function to detect of points are disjoint
+    \note To avoid circular references
+ */
+template <typename Point1, typename Point2>
+inline bool equals_point_point(Point1 const& point1, Point2 const& point2)
+{
+    return ! detail::disjoint::disjoint_point_point(point1, point2);
+}
+
+
+}} // namespace detail::equals
+#endif // DOXYGEN_NO_DETAIL
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_DETAIL_DISJOINT_HPP
Added: sandbox/ggl/formal_review/boost/ggl/algorithms/detail/not.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/algorithms/detail/not.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,45 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_DETAIL_NOT_HPP
+#define GGL_ALGORITHMS_DETAIL_NOT_HPP
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+
+
+/*!
+    \brief Structure negating the result of specified policy
+    \tparam Geometry1 first geometry type
+    \tparam Geometry2 second geometry type
+    \tparam Policy
+    \param geometry1 first geometry
+    \param geometry2 second geometry
+    \return Negation of the result of the policy
+ */
+template <typename Geometry1, typename Geometry2, typename Policy>
+struct not_
+{
+    static inline bool apply(Geometry1 const &geometry1, Geometry2 const& geometry2)
+    {
+        return ! Policy::apply(geometry1, geometry2);
+    }
+};
+
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_DETAIL_NOT_HPP
Added: sandbox/ggl/formal_review/boost/ggl/algorithms/detail/point_on_border.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/algorithms/detail/point_on_border.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,173 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_DETAIL_POINT_ON_BORDER_HPP
+#define GGL_ALGORITHMS_DETAIL_POINT_ON_BORDER_HPP
+
+
+#include <boost/range/functions.hpp>
+
+#include <ggl/core/point_type.hpp>
+#include <ggl/core/ring_type.hpp>
+
+#include <ggl/geometries/concepts/check.hpp>
+
+#include <ggl/algorithms/assign.hpp>
+
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace point_on_border {
+
+template
+<
+    typename Range,
+    typename Point
+>
+struct point_on_range
+{
+    static inline bool apply(Range const& range, Point& point)
+    {
+        if (boost::size(range) > 0)
+        {
+            point = *boost::begin(range);
+            return true;
+        }
+        return false;
+    }
+};
+
+
+template
+<
+    typename Polygon,
+    typename Point
+>
+struct point_on_polygon
+{
+    static inline bool apply(Polygon const& polygon, Point& point)
+    {
+        return point_on_range
+            <
+                typename ring_type<Polygon>::type,
+                Point
+            >::apply(exterior_ring(polygon), point);
+    }
+};
+
+
+template
+<
+    typename Box,
+    typename Point
+>
+struct point_on_box
+{
+    static inline bool apply(Box const& box, Point& point)
+    {
+        detail::assign::assign_box_2d_corner<min_corner, min_corner>(box, point);
+        return true;
+    }
+};
+
+
+}} // namespace detail::point_on_border
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+    typename GeometryTag,
+    typename Geometry,
+    typename Point
+
+>
+struct point_on_border
+{
+};
+
+
+template<typename Point>
+struct point_on_border
+    <
+        point_tag, Point, Point
+    >
+{
+    static inline bool apply(Point const& source, Point& destination)
+    {
+        destination = source;
+        return true;
+    }
+};
+
+
+template<typename Linestring, typename Point>
+struct point_on_border<linestring_tag, Linestring, Point>
+    : detail::point_on_border::point_on_range<Linestring, Point>
+{};
+
+
+template<typename Ring, typename Point>
+struct point_on_border<ring_tag, Ring, Point>
+    : detail::point_on_border::point_on_range<Ring, Point>
+{};
+
+
+template<typename Polygon, typename Point>
+struct point_on_border<polygon_tag, Polygon, Point>
+    : detail::point_on_border::point_on_polygon<Polygon, Point>
+{};
+
+
+template<typename Box, typename Point>
+struct point_on_border<box_tag, Box, Point>
+    : detail::point_on_border::point_on_box<Box, Point>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+    \brief Take point on a border
+    \ingroup utility 
+    \tparam Geometry geometry type
+    \param geometry geometry to take point from
+    \param point 
+    \return TRUE if successful, else false. 
+        It is only false if polygon/line have no points
+    \note for a polygon, it is always a point on the exterior ring
+ */
+template <typename Geometry>
+inline bool point_on_border(Geometry const& geometry,
+    typename point_type<Geometry>::type& point)
+{
+    typedef typename point_type<Geometry>::type point_type;
+
+    concept::check<const Geometry>();
+    concept::check<point_type>();
+
+    return dispatch::point_on_border
+            <
+                typename tag<Geometry>::type,
+                Geometry,
+                point_type
+            >::apply(geometry, point);
+}
+
+
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_DETAIL_POINT_ON_BORDER_HPP
Added: sandbox/ggl/formal_review/boost/ggl/algorithms/disjoint.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/algorithms/disjoint.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,215 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_DISJOINT_HPP
+#define GGL_ALGORITHMS_DISJOINT_HPP
+
+
+/*!
+\defgroup disjoint disjoint: detect if geometries are not spatially related
+\details disjoint means spatially disjoint, there is no overlap of interiors
+    and boundaries, the intersection of interiors or boundaries is empty.
+
+\par Geometries:
+- \b point + \b point (= ! equals)
+- \b point + \b box (= not within or on border)
+- \b box + \b box
+- \b ring + \b box
+- \b polygon + \b box
+- \b polygon + \b ring
+- \b polygon + \b polygon
+
+*/
+
+#include <deque>
+
+
+#include <boost/mpl/if.hpp>
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+#include <boost/static_assert.hpp>
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/coordinate_dimension.hpp>
+#include <ggl/core/is_multi.hpp>
+#include <ggl/core/reverse_dispatch.hpp>
+
+#include <ggl/algorithms/detail/disjoint.hpp>
+#include <ggl/algorithms/detail/point_on_border.hpp>
+#include <ggl/algorithms/overlay/get_intersection_points.hpp>
+#include <ggl/algorithms/within.hpp>
+
+#include <ggl/geometries/concepts/check.hpp>
+
+#include <ggl/util/math.hpp>
+
+
+
+namespace ggl
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace disjoint {
+
+
+template <typename Geometry1, typename Geometry2>
+struct general
+{
+    static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2)
+    {
+
+        typedef typename ggl::point_type<Geometry1>::type point_type;
+        typedef detail::intersection::intersection_point<point_type> ip_type;
+        std::deque<ip_type> ips; // intersection points
+
+        // Get any intersection
+        ggl::get_intersection_points(geometry1, geometry2, ips);
+        if (ips.size() > 0)
+        {
+            return false;
+        }
+        // If there is no intersection of segments, they might ly
+        // inside each other
+        point_type p1;
+        ggl::point_on_border(geometry1, p1);
+        if (ggl::within(p1, geometry2))
+        {
+            return false;
+        }
+
+        typename ggl::point_type<Geometry1>::type p2;
+        ggl::point_on_border(geometry2, p2);
+        if (ggl::within(p2, geometry1))
+        {
+            return false;
+        }
+
+        return true;
+    }
+};
+
+
+}} // namespace detail::disjoint
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template
+<
+    typename GeometryTag1, typename GeometryTag2,
+    typename Geometry1, typename Geometry2,
+    bool IsMulti1, bool IsMulti2,
+    std::size_t DimensionCount
+>
+struct disjoint
+    : detail::disjoint::general<Geometry1, Geometry2>
+{};
+
+
+template <typename Point1, typename Point2, std::size_t DimensionCount>
+struct disjoint<point_tag, point_tag, Point1, Point2, false, false, DimensionCount>
+    : detail::disjoint::point_point<Point1, Point2, 0, DimensionCount>
+{};
+
+
+template <typename Box1, typename Box2, std::size_t DimensionCount>
+struct disjoint<box_tag, box_tag, Box1, Box2, false, false, DimensionCount>
+    : detail::disjoint::box_box<Box1, Box2, 0, DimensionCount>
+{};
+
+
+template <typename Point, typename Box, std::size_t DimensionCount>
+struct disjoint<point_tag, box_tag, Point, Box, false, false, DimensionCount>
+    : detail::disjoint::point_box<Point, Box, 0, DimensionCount>
+{};
+
+
+template
+<
+    typename GeometryTag1, typename GeometryTag2,
+    typename G1, typename G2,
+    bool IsMulti1, bool IsMulti2,
+    std::size_t DimensionCount
+>
+struct disjoint_reversed
+{
+    static inline bool apply(G1 const& g1, G2 const& g2)
+    {
+        return disjoint
+            <
+                GeometryTag2, GeometryTag1,
+                G2, G1,
+                IsMulti2, IsMulti1,
+                DimensionCount
+            >::apply(g2, g1);
+    }
+};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+
+/*!
+    \brief Calculate if two geometries are disjoint
+    \ingroup disjoint
+    \tparam Geometry1 first geometry type
+    \tparam Geometry2 second geometry type
+    \param geometry1 first geometry
+    \param geometry2 second geometry
+    \return true if disjoint, else false
+ */
+template <typename Geometry1, typename Geometry2>
+inline bool disjoint(const Geometry1& geometry1,
+            const Geometry2& geometry2)
+{
+    concept::check_concepts_and_equal_dimensions
+        <
+            const Geometry1,
+            const Geometry2
+        >();
+
+    typedef typename boost::remove_const<Geometry1>::type ncg1_type;
+    typedef typename boost::remove_const<Geometry2>::type ncg2_type;
+
+    return boost::mpl::if_c
+        <
+            reverse_dispatch<Geometry1, Geometry2>::type::value,
+            dispatch::disjoint_reversed
+            <
+                typename tag<ncg1_type>::type,
+                typename tag<ncg2_type>::type,
+                ncg1_type,
+                ncg2_type,
+                is_multi<ncg1_type>::type::value,
+                is_multi<ncg2_type>::type::value,
+                dimension<ncg1_type>::type::value
+            >,
+            dispatch::disjoint
+            <
+                typename tag<ncg1_type>::type,
+                typename tag<ncg2_type>::type,
+                ncg1_type,
+                ncg2_type,
+                is_multi<ncg1_type>::type::value,
+                is_multi<ncg2_type>::type::value,
+                dimension<ncg1_type>::type::value
+            >
+        >::type::apply(geometry1, geometry2);
+}
+
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_DISJOINT_HPP
Added: sandbox/ggl/formal_review/boost/ggl/algorithms/distance.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/algorithms/distance.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,366 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_DISTANCE_HPP
+#define GGL_ALGORITHMS_DISTANCE_HPP
+
+#include <boost/mpl/if.hpp>
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+#include <boost/static_assert.hpp>
+
+#include <ggl/core/cs.hpp>
+#include <ggl/core/is_multi.hpp>
+#include <ggl/core/reverse_dispatch.hpp>
+
+#include <ggl/geometries/segment.hpp>
+#include <ggl/geometries/concepts/check.hpp>
+
+#include <ggl/strategies/distance.hpp>
+#include <ggl/strategies/distance_result.hpp>
+
+/*!
+\defgroup distance distance: calculate distance between two geometries
+The distance algorithm returns the distance between two geometries.
+\par Coordinate systems and strategies:
+With help of strategies the distance function returns the appropriate distance.
+If the input is in cartesian coordinates, the Euclidian distance (Pythagoras) is calculated.
+If the input is in spherical coordinates (either degree or radian), the distance over the sphere is returned.
+If the input is in geographic coordinates, distance is calculated over the globe and returned in meters.
+
+\par Distance result:
+Depending on calculation type the distance result is either a structure, convertable
+to a double, or a double value. In case of Pythagoras it makes sense to not draw the square root in the
+strategy itself. Taking a square root is relative expensive and is not necessary when comparing distances.
+
+\par Geometries:
+Currently implemented, for both cartesian and spherical/geographic:
+- POINT - POINT
+- POINT - SEGMENT and v.v.
+- POINT - LINESTRING and v.v.
+
+Not yet implemented:
+- POINT - RING etc, note that it will return a zero if the point is anywhere within the ring
+
+\par Example:
+Example showing distance calculation of two points, in xy and in latlong coordinates
+\dontinclude doxygen_1.cpp
+\skip example_distance_point_point
+\line {
+\until }
+*/
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace distance {
+
+template <typename P1, typename P2, typename Strategy>
+struct point_to_point
+{
+    static inline typename Strategy::return_type apply(P1 const& p1,
+                P2 const& p2, Strategy const& strategy)
+    {
+        return strategy.apply(p1, p2);
+    }
+};
+
+
+template<typename Point, typename Segment, typename Strategy>
+struct point_to_segment
+{
+    static inline typename Strategy::return_type apply(Point const& point,
+                Segment const& segment, Strategy const& strategy)
+    {
+        typename strategy_distance_segment
+            <
+            typename cs_tag<Point>::type,
+            typename cs_tag<Segment>::type,
+            Point,
+            typename point_type<Segment>::type
+            >::type segment_strategy;
+
+        return segment_strategy.apply(point, segment.first, segment.second);
+    }
+};
+
+
+template<typename P, typename L, typename PPStrategy, typename PSStrategy>
+struct point_to_linestring
+{
+    typedef typename PPStrategy::return_type return_type;
+
+    static inline return_type apply(P const& point, L const& linestring,
+            PPStrategy const& pp_strategy, PSStrategy const& ps_strategy)
+    {
+        typedef segment<const typename point_type<L>::type> segment_type;
+
+        if (boost::begin(linestring) == boost::end(linestring))
+        {
+            return return_type(0);
+        }
+
+        // line of one point: return point square_distance
+        typedef typename boost::range_const_iterator<L>::type iterator_type;
+        iterator_type it = boost::begin(linestring);
+        iterator_type prev = it++;
+        if (it == boost::end(linestring))
+        {
+            return pp_strategy.apply(point, *boost::begin(linestring));
+        }
+
+
+        // start with first segment distance
+        return_type d = ps_strategy.apply(point, *prev, *it);
+
+        // check if other segments are closer
+        prev = it++;
+        while(it != boost::end(linestring))
+        {
+            return_type ds = ps_strategy.apply(point, *prev, *it);
+            if (ggl::close_to_zero(ds))
+            {
+                return return_type(0);
+            }
+            else if (ds < d)
+            {
+                d = ds;
+            }
+            prev = it++;
+        }
+
+        return d;
+    }
+};
+
+
+
+}} // namespace detail::distance
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+    typename GeometryTag1, typename GeometryTag2,
+    typename G1, typename G2,
+    typename StrategyTag, typename Strategy,
+    bool IsMulti1, bool IsMulti2
+>
+struct distance
+{};
+
+
+template <typename P1, typename P2, typename Strategy>
+struct distance
+<
+    point_tag, point_tag,
+    P1, P2,
+    strategy_tag_distance_point_point, Strategy,
+    false, false
+> : detail::distance::point_to_point<P1, P2, Strategy>
+{};
+
+/// Point-line version 1, where point-point strategy is specified
+template <typename Point, typename Linestring, typename Strategy>
+struct distance
+<
+    point_tag, linestring_tag,
+    Point, Linestring,
+    strategy_tag_distance_point_point, Strategy,
+    false, false
+>
+{
+
+    static inline typename Strategy::return_type apply(Point const& point,
+            Linestring const& linestring,
+            Strategy const& strategy)
+    {
+        //typedef segment<const > segment_type;
+        typedef typename ggl::strategy_distance_segment
+                    <
+                            typename cs_tag<Point>::type,
+                            typename cs_tag<Linestring>::type,
+                            Point,
+                            typename point_type<Linestring>::type
+                    >::type ps_strategy_type;
+
+        return detail::distance::point_to_linestring
+            <
+                Point, Linestring, Strategy, ps_strategy_type
+            >::apply(point, linestring, strategy, ps_strategy_type());
+    }
+};
+
+
+/// Point-line version 2, where point-segment strategy is specified
+template <typename Point, typename Linestring, typename Strategy>
+struct distance
+<
+    point_tag, linestring_tag,
+    Point, Linestring,
+    strategy_tag_distance_point_segment, Strategy,
+    false, false
+>
+{
+    static inline typename Strategy::return_type apply(Point const& point,
+            Linestring const& linestring,
+            Strategy const& strategy)
+    {
+        typedef typename Strategy::point_strategy_type pp_strategy_type;
+        return detail::distance::point_to_linestring
+            <
+                Point, Linestring, pp_strategy_type, Strategy
+            >::apply(point, linestring, pp_strategy_type(), strategy);
+    }
+};
+
+
+template <typename Point, typename Segment, typename Strategy>
+struct distance
+<
+    point_tag, segment_tag,
+    Point, Segment,
+    strategy_tag_distance_point_point, Strategy,
+    false, false
+> : detail::distance::point_to_segment<Point, Segment, Strategy>
+{};
+
+
+// Strictly spoken this might be in namespace <impl> again
+template
+<
+    typename GeometryTag1, typename GeometryTag2,
+    typename G1, typename G2,
+    typename StrategyTag, typename Strategy,
+    bool IsMulti1, bool IsMulti2
+>
+struct distance_reversed
+{
+    static inline typename Strategy::return_type apply(G1 const& g1,
+                G2 const& g2, Strategy const& strategy)
+    {
+        return distance
+            <
+                GeometryTag2, GeometryTag1,
+                G2, G1,
+                StrategyTag, Strategy,
+                IsMulti2, IsMulti1
+            >::apply(g2, g1, strategy);
+    }
+};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+/*!
+    \brief Calculate distance between two geometries with a specified strategy
+    \ingroup distance
+    \tparam Geometry1 first geometry type
+    \tparam Geometry2 second geometry type
+    \tparam S point-point-distance strategy type
+    \param geometry1 first geometry
+    \param geometry2 second geometry
+    \param strategy strategy to calculate distance between two points
+    \return the distance (either a double or a distance_result, (convertable to double))
+    \note The strategy can be a point-point strategy. In case of distance point-line/point-polygon
+        it may also be a point-segment strategy.
+    \par Example:
+    Example showing distance calculation of two lat long points, using the accurate Vincenty approximation
+    \dontinclude doxygen_1.cpp
+    \skip example_distance_point_point_strategy
+    \line {
+    \until }
+ */
+template <typename Geometry1, typename Geometry2, typename Strategy>
+inline typename Strategy::return_type distance(Geometry1 const& geometry1,
+            Geometry2 const& geometry2, Strategy const& strategy)
+{
+    typedef typename boost::remove_const<Geometry1>::type ncg1_type;
+    typedef typename boost::remove_const<Geometry2>::type ncg2_type;
+
+    return boost::mpl::if_c
+        <
+            ggl::reverse_dispatch<Geometry1, Geometry2>::type::value,
+            dispatch::distance_reversed
+                <
+                    typename tag<ncg1_type>::type,
+                    typename tag<ncg2_type>::type,
+                    ncg1_type,
+                    ncg2_type,
+                    typename strategy_tag<Strategy>::type,
+                    Strategy,
+                    is_multi<ncg1_type>::value,
+                    is_multi<ncg2_type>::value
+                >,
+                dispatch::distance
+                <
+                    typename tag<ncg1_type>::type,
+                    typename tag<ncg2_type>::type,
+                    ncg1_type,
+                    ncg2_type,
+                    typename strategy_tag<Strategy>::type,
+                    Strategy,
+                    is_multi<ncg1_type>::value,
+                    is_multi<ncg2_type>::value
+                >
+        >::type::apply(geometry1, geometry2, strategy);
+}
+
+
+/*!
+    \brief Calculate distance between two geometries
+    \ingroup distance
+    \details The default strategy is used, belonging to the corresponding coordinate system of the geometries
+    \tparam G1 first geometry type
+    \tparam G2 second geometry type
+    \param geometry1 first geometry
+    \param geometry2 second geometry
+    \return the distance (either a double or a distance result, convertable to double)
+ */
+template <typename Geometry1, typename Geometry2>
+inline typename distance_result<Geometry1, Geometry2>::type distance(
+                Geometry1 const& geometry1, Geometry2 const& geometry2)
+{
+    concept::check<const Geometry1>();
+    concept::check<const Geometry2>();
+
+    typedef typename point_type<Geometry1>::type point1_type;
+    typedef typename point_type<Geometry2>::type point2_type;
+
+    // Define a point-point-distance-strategy
+    // for either the normal case, either the reversed case
+    typedef typename boost::mpl::if_c
+        <
+            ggl::reverse_dispatch<Geometry1, Geometry2>::type::value,
+            typename strategy_distance
+                <
+                    typename cs_tag<point2_type>::type,
+                    typename cs_tag<point1_type>::type,
+                    point2_type,
+                    point1_type
+                >::type,
+            typename strategy_distance
+                <
+                    typename cs_tag<point1_type>::type,
+                    typename cs_tag<point2_type>::type,
+                    point1_type,
+                    point2_type
+                >::type
+        >::type strategy;
+
+    return distance(geometry1, geometry2, strategy());
+}
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_DISTANCE_HPP
Added: sandbox/ggl/formal_review/boost/ggl/algorithms/envelope.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/algorithms/envelope.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,282 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_ENVELOPE_HPP
+#define GGL_ALGORITHMS_ENVELOPE_HPP
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <ggl/algorithms/combine.hpp>
+#include <ggl/algorithms/convert.hpp>
+#include <ggl/core/cs.hpp>
+#include <ggl/core/exterior_ring.hpp>
+#include <ggl/geometries/concepts/check.hpp>
+
+/*!
+\defgroup envelope envelope: calculate envelope (minimum bounding rectangle) of a geometry
+\par Source descriptions:
+- OGC: Envelope (): Geometry - The minimum bounding rectangle (MBR) for this
+    Geometry,
+returned as a Geometry. The polygon is defined by the corner points of the
+    bounding box
+    [(MINX, MINY), (MAXX, MINY), (MAXX, MAXY), (MINX, MAXY), (MINX, MINY)].
+
+\note Implemented in the Generic Geometry Library: The minimum bounding box,
+    always as a box, having min <= max
+
+The envelope algorithm calculates the bounding box, or envelope, of a geometry.
+There are two versions:
+- envelope, taking a reference to a box as second parameter
+- make_envelope, returning a newly constructed box (type as a template parameter
+    in the function call)
+
+\par Geometries:
+- \b point: a box with zero area, the maximum and the minimum point of the box are
+set to the point itself.
+- \b linestring, \b ring or \b range is the smallest box that contains all points of the
+    specified point sequence.
+If the linestring is empty, the envelope is the inverse infinite box, that is,
+    the minimum point is very large (max infinite) and the maximum point is
+    very small (min infinite).
+- \b polygon, the envelope of the outer ring
+\image html envelope_polygon.png
+
+\par Example:
+Example showing envelope calculation
+\dontinclude doxygen_1.cpp
+\skip example_envelope_linestring
+\line {
+\until }
+*/
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace envelope {
+
+
+/// Calculate envelope of an 2D or 3D segment
+template<typename Geometry, typename Box>
+struct envelope_combine_one
+{
+    static inline void apply(Geometry const& geometry, Box& mbr)
+    {
+        assign_inverse(mbr);
+        ggl::combine(mbr, geometry);
+    }
+};
+
+
+/// Iterate through range (also used in multi*)
+template<typename Range, typename Box>
+inline void envelope_range_additional(Range const& range, Box& mbr)
+{
+    typedef typename boost::range_const_iterator<Range>::type iterator_type;
+
+    for (iterator_type it = boost::begin(range);
+        it != boost::end(range);
+        ++it)
+    {
+        ggl::combine(mbr, *it);
+    }
+}
+
+
+
+/// Generic range dispatching struct
+template <typename Range, typename Box>
+struct envelope_range
+{
+    /// Calculate envelope of range using a strategy
+    static inline void apply(Range const& range, Box& mbr)
+    {
+        assign_inverse(mbr);
+        envelope_range_additional(range, mbr);
+    }
+};
+
+}} // namespace detail::envelope
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+// Note, the strategy is for future use (less/greater -> compare spherical
+// using other methods), defaults are OK for now.
+// However, they are already in the template methods
+
+template
+<
+    typename Tag1, typename Tag2,
+    typename Geometry, typename Box,
+    typename StrategyLess, typename StrategyGreater
+>
+struct envelope {};
+
+
+template
+<
+    typename Point, typename Box,
+    typename StrategyLess, typename StrategyGreater
+>
+struct envelope
+    <
+        point_tag, box_tag,
+        Point, Box,
+        StrategyLess, StrategyGreater
+    >
+    : detail::envelope::envelope_combine_one<Point, Box>
+{};
+
+
+template
+<
+    typename BoxIn, typename BoxOut,
+    typename StrategyLess, typename StrategyGreater
+>
+struct envelope
+    <
+        box_tag, box_tag,
+        BoxIn, BoxOut,
+        StrategyLess, StrategyGreater
+    >
+    : detail::envelope::envelope_combine_one<BoxIn, BoxOut>
+{};
+
+
+template
+<
+    typename Segment, typename Box,
+    typename StrategyLess, typename StrategyGreater
+>
+struct envelope
+    <
+        segment_tag, box_tag,
+        Segment, Box,
+        StrategyLess, StrategyGreater
+    >
+    : detail::envelope::envelope_combine_one<Segment, Box>
+{};
+
+
+template
+<
+    typename Linestring, typename Box,
+    typename StrategyLess, typename StrategyGreater
+>
+struct envelope
+    <
+        linestring_tag, box_tag,
+        Linestring, Box,
+        StrategyLess, StrategyGreater
+    >
+    : detail::envelope::envelope_range<Linestring, Box>
+{};
+
+
+template
+<
+    typename Ring, typename Box,
+    typename StrategyLess, typename StrategyGreater
+>
+struct envelope
+    <
+        ring_tag, box_tag,
+        Ring, Box,
+        StrategyLess, StrategyGreater
+    >
+    : detail::envelope::envelope_range<Ring, Box>
+{};
+
+
+template
+<
+    typename Polygon, typename Box,
+    typename StrategyLess, typename StrategyGreater
+>
+struct envelope
+    <
+        polygon_tag, box_tag,
+        Polygon, Box,
+        StrategyLess, StrategyGreater
+    >
+{
+    static inline void apply(Polygon const& poly, Box& mbr)
+    {
+        // For polygon, inspecting outer ring is sufficient
+
+        detail::envelope::envelope_range
+            <
+                typename ring_type<Polygon>::type,
+                Box
+            >::apply(exterior_ring(poly), mbr);
+    }
+
+};
+
+
+} // namespace dispatch
+#endif
+
+
+/*!
+\brief Calculate envelope of a geometry
+\ingroup envelope
+\param geometry the geometry
+\param mbr the box receiving the envelope
+\par Example:
+Example showing envelope calculation, using point_ll latlong points
+\dontinclude doxygen_1.cpp
+\skip example_envelope_polygon
+\line {
+\until }
+*/
+template<typename Geometry, typename Box>
+inline void envelope(Geometry const& geometry, Box& mbr)
+{
+    concept::check<const Geometry>();
+    concept::check<Box>();
+
+    dispatch::envelope
+        <
+            typename tag<Geometry>::type, typename tag<Box>::type,
+            Geometry, Box,
+            void, void
+        >::apply(geometry, mbr);
+}
+
+
+/*!
+\brief Calculate and return envelope of a geometry
+\ingroup envelope
+\param geometry the geometry
+*/
+template<typename Box, typename Geometry>
+inline Box make_envelope(Geometry const& geometry)
+{
+    concept::check<const Geometry>();
+    concept::check<Box>();
+
+    Box mbr;
+    dispatch::envelope
+        <
+            typename tag<Geometry>::type, typename tag<Box>::type,
+            Geometry, Box,
+            void, void
+        >::apply(geometry, mbr);
+    return mbr;
+}
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_ENVELOPE_HPP
Added: sandbox/ggl/formal_review/boost/ggl/algorithms/equals.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/algorithms/equals.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,319 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_EQUALS_HPP
+#define GGL_ALGORITHMS_EQUALS_HPP
+
+/*!
+\defgroup equals equals: detect if two geometries are spatially equal
+\par Geometries:
+- \b point + \b point
+- \b box + \b box
+
+*/
+
+
+#include <cstddef>
+#include <deque>
+
+#include <boost/static_assert.hpp>
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/coordinate_dimension.hpp>
+#include <ggl/core/is_multi.hpp>
+#include <ggl/core/interior_rings.hpp>
+
+#include <ggl/algorithms/detail/disjoint.hpp>
+#include <ggl/algorithms/detail/not.hpp>
+#include <ggl/algorithms/area.hpp>
+#include <ggl/algorithms/overlay/get_intersection_points.hpp>
+#include <ggl/algorithms/overlay/merge_intersection_points.hpp>
+#include <ggl/geometries/concepts/check.hpp>
+#include <ggl/util/math.hpp>
+
+
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace equals {
+
+
+template
+<
+    typename Box1,
+    typename Box2,
+    std::size_t Dimension,
+    std::size_t DimensionCount
+>
+struct box_box
+{
+    static inline bool apply(Box1 const& box1, Box2 const& box2)
+    {
+        if (!ggl::math::equals(get<min_corner, Dimension>(box1), get<min_corner, Dimension>(box2))
+            || !ggl::math::equals(get<max_corner, Dimension>(box1), get<max_corner, Dimension>(box2)))
+        {
+            return false;
+        }
+        return box_box<Box1, Box2, Dimension + 1, DimensionCount>::apply(box1, box2);
+    }
+};
+
+template <typename Box1, typename Box2, std::size_t DimensionCount>
+struct box_box<Box1, Box2, DimensionCount, DimensionCount>
+{
+    static inline bool apply(Box1 const& , Box2 const& )
+    {
+        return true;
+    }
+};
+
+
+template <typename Ring1, typename Ring2>
+struct ring_ring
+{
+    static inline bool apply(Ring1 const& ring1, Ring2 const& ring2, bool check_area = true)
+    {
+        // Note: this implementation makes use of getting interections
+        // and merge them. If all IP's disappear, the ring should be the same
+        // (because merging removes collinear or non-collinear
+        // IP's following the same path)
+        // However, this implementation should be redone using
+        // a linear time algorithm (getting left-most points of both
+        // and follow them using circular iterator and distance/side)
+
+        // obvious check, area's should be the same.
+        if (check_area && ggl::area(ring1) != ggl::area(ring2))
+        {
+            return false;
+        }
+        // We could check more (perimeter,centroid,envelope)
+        // For now we go directly to intersection points
+
+        typedef typename ggl::point_type<Ring1>::type point_type;
+        typedef detail::intersection::intersection_point<point_type> ip_type;
+        typedef std::deque<ip_type> container_type;
+
+        container_type ips;
+
+
+        bool trivial = ggl::get_intersection_points(ring1, ring2, ips);
+        if (trivial || ips.size() == 0)
+        {
+            return false;
+        }
+        ggl::merge_intersection_points(ips);
+        if (ips.size() == 0)
+        {
+            // All IP's are merged. Meaning collinear / path can be followed
+            return true;
+        }
+
+        return false;
+    }
+};
+
+
+template <typename Polygon1, typename Polygon2>
+struct polygon_polygon
+{
+
+    struct sortable
+    {
+        int index;
+        double area;
+        bool counterpart_found;
+        inline sortable(int i, double a)
+            : index(i)
+            , area(a)
+            , counterpart_found(false)
+        {}
+
+        inline bool operator<(sortable const& other) const
+        {
+            return area < other.area;
+        }
+    };
+
+
+    template <typename Poly>
+    static inline void fill_sortable(Poly const& polygon, std::vector<sortable>& v)
+    {
+        int i = 0;
+        for (typename boost::range_const_iterator
+                <
+                    typename interior_type<Poly>::type
+                >::type it = boost::begin(interior_rings(polygon));
+             it != boost::end(interior_rings(polygon));
+             ++it, ++i)
+        {
+            v.push_back(sortable(i, ggl::area(*it)));
+        }
+        std::sort(v.begin(), v.end());
+
+        /***
+        for (typename std::vector<sortable>::iterator it = v.begin();
+            it != v.end();
+            ++it)
+        {
+            std::cout << "Ring: " << it->index << " area: " << it->area << std::endl;
+        }
+        ***/
+    }
+
+    static inline bool apply(Polygon1 const& polygon1, Polygon2 const& polygon2)
+    {
+        // Check number of rings (area check is done in exterior ring check)
+        if (ggl::num_interior_rings(polygon1) != ggl::num_interior_rings(polygon2))
+        {
+            return false;
+        }
+
+        typedef typename ggl::ring_type<Polygon1>::type ring_type1;
+        typedef typename ggl::ring_type<Polygon2>::type ring_type2;
+        typedef ring_ring<ring_type1, ring_type2> compare;
+
+        // Check exterior ring
+        if (! compare::apply(exterior_ring(polygon1), exterior_ring(polygon2)))
+        {
+            return false;
+        }
+
+        // Check interior rings -> first sort them on area ,
+        // for performance reasons (area is not re-calculated in ring-compare)
+        std::vector<sortable> int1, int2;
+
+        fill_sortable(polygon1, int1);
+        fill_sortable(polygon2, int2);
+
+        std::size_t n = 0;
+
+        typename interior_type<Polygon1>::type const& rings1
+                = interior_rings(polygon1);
+        typename interior_type<Polygon2>::type const& rings2
+                = interior_rings(polygon2);
+
+        // Compare all rings (having equal area)
+        for (typename std::vector<sortable>::iterator it1 = int1.begin();
+            it1 != int1.end();
+            ++it1)
+        {
+            for (typename std::vector<sortable>::iterator it2 = int2.begin();
+                ! it1->counterpart_found
+                    && it2 != int2.end()
+                    && it2->area <= it1->area; //+epsilon
+                ++it2)
+            {
+                if (! it2->counterpart_found
+                    && ggl::math::equals(it1->area, it2->area))
+                {
+                    if (compare::apply(rings1[it1->index],
+                            rings2[it2->index], false))
+                    {
+                        it1->counterpart_found = true;
+                        it2->counterpart_found = true;
+                        n++;
+                    }
+                }
+            }
+        }
+
+        return n == ggl::num_interior_rings(polygon1);
+    }
+};
+
+
+}} // namespace detail::equals
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+    typename Tag1, typename Tag2,
+    bool IsMulti1, bool IsMulti2,
+    typename Geometry1,
+    typename Geometry2,
+    std::size_t DimensionCount
+>
+struct equals
+{};
+
+
+template <typename P1, typename P2, std::size_t DimensionCount>
+struct equals<point_tag, point_tag, false, false, P1, P2, DimensionCount>
+    : ggl::detail::not_
+        <
+            P1,
+            P2,
+            detail::disjoint::point_point<P1, P2, 0, DimensionCount>
+        >
+{};
+
+
+template <typename Box1, typename Box2, std::size_t DimensionCount>
+struct equals<box_tag, box_tag, false, false, Box1, Box2, DimensionCount>
+    : detail::equals::box_box<Box1, Box2, 0, DimensionCount>
+{};
+
+
+template <typename Ring1, typename Ring2>
+struct equals<ring_tag, ring_tag, false, false, Ring1, Ring2, 2>
+    : detail::equals::ring_ring<Ring1, Ring2>
+{};
+
+template <typename Polygon1, typename Polygon2>
+struct equals<polygon_tag, polygon_tag, false, false, Polygon1, Polygon2, 2>
+    : detail::equals::polygon_polygon<Polygon1, Polygon2>
+{};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+    \brief Detect if two geometries are spatially equal
+    \ingroup equals
+    \tparam Geometry1 first geometry type
+    \tparam Geometry2 second geometry type
+    \param geometry1 first geometry
+    \param geometry2 second geometry
+    \return true if geometries are spatially equal, else false
+ */
+template <typename Geometry1, typename Geometry2>
+inline bool equals(Geometry1 const& geometry1, Geometry2 const& geometry2)
+{
+    concept::check_concepts_and_equal_dimensions
+        <
+            const Geometry1,
+            const Geometry2
+        >();
+
+
+    return dispatch::equals
+            <
+                typename tag<Geometry1>::type,
+                typename tag<Geometry2>::type,
+                is_multi<Geometry1>::type::value,
+                is_multi<Geometry2>::type::value,
+                Geometry1,
+                Geometry2,
+                dimension<Geometry1>::type::value
+            >::apply(geometry1, geometry2);
+}
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_EQUALS_HPP
+
Added: sandbox/ggl/formal_review/boost/ggl/algorithms/for_each.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/algorithms/for_each.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,357 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_FOR_EACH_HPP
+#define GGL_ALGORITHMS_FOR_EACH_HPP
+
+/*!
+\defgroup for_each for_each: apply a functor to each point or segment of a geometry
+\details There are two algorithms provided which walk through the points or segments
+of linestrings and polygons. They are called for_each_point, for_each_segment,
+after the standard library
+\note For both for_each algorithms there is a \b const and a non-const version provided.
+*/
+
+#include <algorithm>
+
+
+#include <ggl/core/exterior_ring.hpp>
+#include <ggl/core/interior_rings.hpp>
+#include <ggl/core/is_multi.hpp>
+
+#include <ggl/geometries/concepts/check.hpp>
+
+#include <ggl/geometries/segment.hpp>
+
+#include <ggl/util/add_const_if_c.hpp>
+#include <ggl/util/range_iterator_const_if_c.hpp>
+
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace for_each {
+
+
+template <typename Point, typename Functor, bool IsConst>
+struct fe_point_per_point
+{
+    static inline Functor apply(
+                typename add_const_if_c<IsConst, Point>::type& point, Functor f)
+    {
+        f(point);
+        return f;
+    }
+};
+
+
+template <typename Point, typename Functor, bool IsConst>
+struct fe_point_per_segment
+{
+    static inline Functor apply(
+                typename add_const_if_c<IsConst, Point>::type& point, Functor f)
+    {
+        return f;
+    }
+};
+
+
+template <typename Range, typename Functor, bool IsConst>
+struct fe_range_per_point
+{
+    static inline Functor apply(
+                    typename add_const_if_c<IsConst, Range>::type& range,
+                    Functor f)
+    {
+        return (std::for_each(boost::begin(range), boost::end(range), f));
+    }
+};
+
+
+template <typename Range, typename Functor, bool IsConst>
+struct fe_range_per_segment
+{
+    static inline Functor apply(
+                typename add_const_if_c<IsConst, Range>::type& range,
+                Functor f)
+    {
+        typedef typename range_iterator_const_if_c
+            <
+                IsConst,
+                Range
+            >::type iterator_type;
+
+        typedef typename add_const_if_c
+            <
+                IsConst,
+                typename point_type<Range>::type
+            >::type point_type;
+
+        iterator_type it = boost::begin(range);
+        iterator_type previous = it++;
+        while(it != boost::end(range))
+        {
+            segment<point_type> s(*previous, *it);
+            f(s);
+            previous = it++;
+        }
+
+        return f;
+    }
+};
+
+
+template <typename Polygon, typename Functor, bool IsConst>
+struct fe_polygon_per_point
+{
+    static inline Functor apply(
+                typename add_const_if_c<IsConst, Polygon>::type& poly,
+                Functor f)
+    {
+        typedef typename range_iterator_const_if_c
+            <
+                IsConst,
+                typename interior_type<Polygon>::type
+            >::type iterator_type;
+
+        typedef fe_range_per_point
+                <
+                    typename ring_type<Polygon>::type,
+                    Functor,
+                    IsConst
+                > per_ring;
+
+        f = per_ring::apply(exterior_ring(poly), f);
+
+        for (iterator_type it = boost::begin(interior_rings(poly));
+             it != boost::end(interior_rings(poly));
+             ++it)
+        {
+            f = per_ring::apply(*it, f);
+        }
+
+        return f;
+    }
+
+};
+
+
+template <typename Polygon, typename Functor, bool IsConst>
+struct fe_polygon_per_segment
+{
+    static inline Functor apply(
+                typename add_const_if_c<IsConst, Polygon>::type& poly,
+                Functor f)
+    {
+        typedef typename range_iterator_const_if_c
+            <
+                IsConst,
+                typename interior_type<Polygon>::type
+            >::type iterator_type;
+
+        typedef fe_range_per_segment
+            <
+                typename ring_type<Polygon>::type,
+                Functor,
+                IsConst
+            > per_ring;
+
+        f = per_ring::apply(exterior_ring(poly), f);
+
+        for (iterator_type it = boost::begin(interior_rings(poly));
+             it != boost::end(interior_rings(poly));
+             ++it)
+        {
+            f = per_ring::apply(*it, f);
+        }
+
+        return f;
+    }
+
+};
+
+
+}} // namespace detail::for_each
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+    typename Tag,
+    bool IsMulti,
+    typename Geometry,
+    typename Functor,
+    bool IsConst
+>
+struct for_each_point {};
+
+
+template <typename Point, typename Functor, bool IsConst>
+struct for_each_point<point_tag, false, Point, Functor, IsConst>
+    : detail::for_each::fe_point_per_point<Point, Functor, IsConst>
+{};
+
+
+template <typename Linestring, typename Functor, bool IsConst>
+struct for_each_point<linestring_tag, false, Linestring, Functor, IsConst>
+    : detail::for_each::fe_range_per_point<Linestring, Functor, IsConst>
+{};
+
+
+template <typename Ring, typename Functor, bool IsConst>
+struct for_each_point<ring_tag, false, Ring, Functor, IsConst>
+    : detail::for_each::fe_range_per_point<Ring, Functor, IsConst>
+{};
+
+
+template <typename Polygon, typename Functor, bool IsConst>
+struct for_each_point<polygon_tag, false, Polygon, Functor, IsConst>
+    : detail::for_each::fe_polygon_per_point<Polygon, Functor, IsConst>
+{};
+
+
+template
+<
+    typename Tag,
+    bool IsMulti,
+    typename Geometry,
+    typename Functor,
+    bool IsConst
+>
+struct for_each_segment {};
+
+template <typename Point, typename Functor, bool IsConst>
+struct for_each_segment<point_tag, false, Point, Functor, IsConst>
+    : detail::for_each::fe_point_per_segment<Point, Functor, IsConst>
+{};
+
+
+template <typename Linestring, typename Functor, bool IsConst>
+struct for_each_segment<linestring_tag, false, Linestring, Functor, IsConst>
+    : detail::for_each::fe_range_per_segment<Linestring, Functor, IsConst>
+{};
+
+
+template <typename Ring, typename Functor, bool IsConst>
+struct for_each_segment<ring_tag, false, Ring, Functor, IsConst>
+    : detail::for_each::fe_range_per_segment<Ring, Functor, IsConst>
+{};
+
+
+template <typename Polygon, typename Functor, bool IsConst>
+struct for_each_segment<polygon_tag, false, Polygon, Functor, IsConst>
+    : detail::for_each::fe_polygon_per_segment<Polygon, Functor, IsConst>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+    \brief Calls functor for geometry
+    \ingroup loop
+    \param geometry geometry to loop through
+    \param f functor to use
+    \details Calls the functor the specified \b const geometry
+*/
+template<typename Geometry, typename Functor>
+inline Functor for_each_point(Geometry const& geometry, Functor f)
+{
+    concept::check<const Geometry>();
+
+    return dispatch::for_each_point
+        <
+            typename tag<Geometry>::type,
+            is_multi<Geometry>::type::value,
+            Geometry,
+            Functor,
+            true
+        >::apply(geometry, f);
+}
+
+
+/*!
+    \brief Calls functor for geometry
+    \ingroup loop
+    \param geometry geometry to loop through
+    \param f functor to use
+    \details Calls the functor for the specified geometry
+*/
+template<typename Geometry, typename Functor>
+inline Functor for_each_point(Geometry& geometry, Functor f)
+{
+    concept::check<Geometry>();
+
+    return dispatch::for_each_point
+        <
+            typename tag<Geometry>::type,
+            is_multi<Geometry>::type::value,
+            Geometry,
+            Functor,
+            false
+        >::apply(geometry, f);
+}
+
+
+/*!
+    \brief Calls functor for segments on linestrings, rings, polygons, ...
+    \ingroup loop
+    \param geometry geometry to loop through
+    \param f functor to use
+    \details Calls the functor all \b const segments of the
+        specified \b const geometry
+*/
+template<typename Geometry, typename Functor>
+inline Functor for_each_segment(Geometry const& geometry, Functor f)
+{
+    concept::check<const Geometry>();
+
+    return dispatch::for_each_segment
+        <
+            typename tag<Geometry>::type,
+            is_multi<Geometry>::type::value,
+            Geometry,
+            Functor,
+            true
+        >::apply(geometry, f);
+}
+
+
+/*!
+    \brief Calls functor for segments on linestrings, rings, polygons, ...
+    \ingroup loop
+    \param geometry geometry to loop through
+    \param f functor to use
+    \details Calls the functor all segments of the specified geometry
+*/
+template<typename Geometry, typename Functor>
+inline Functor for_each_segment(Geometry& geometry, Functor f)
+{
+    concept::check<Geometry>();
+
+    return dispatch::for_each_segment
+        <
+            typename tag<Geometry>::type,
+            is_multi<Geometry>::type::value,
+            Geometry,
+            Functor,
+            false
+        >::apply(geometry, f);
+}
+
+
+} // namespace ggl
+
+
+#endif // GGL_ALGORITHMS_FOR_EACH_HPP
Added: sandbox/ggl/formal_review/boost/ggl/algorithms/get_section.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/algorithms/get_section.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,116 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_GET_SECTION_HPP
+#define GGL_ALGORITHMS_GET_SECTION_HPP
+
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/exterior_ring.hpp>
+#include <ggl/core/interior_rings.hpp>
+
+#include <ggl/iterators/range_type.hpp>
+
+#include <ggl/geometries/segment.hpp>
+
+
+
+namespace ggl
+{
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Tag, typename Geometry, typename Section>
+struct get_section
+{
+    typedef typename boost::range_const_iterator
+        <
+            typename ggl::range_type<Geometry>::type
+        >::type iterator_type;
+
+    static inline void apply(Geometry const& geometry, Section const& section,
+                iterator_type& begin, iterator_type& end)
+    {
+        begin = boost::begin(geometry) + section.begin_index;
+        end = boost::begin(geometry) + section.end_index + 1;
+    }
+};
+
+template <typename Polygon, typename Section>
+struct get_section<polygon_tag, Polygon, Section>
+{
+    typedef typename boost::range_const_iterator
+        <
+            typename ggl::range_type<Polygon>::type
+        >::type iterator_type;
+
+    static inline void apply(Polygon const& polygon, Section const& section,
+                iterator_type& begin, iterator_type& end)
+    {
+        typedef typename ggl::ring_type<Polygon>::type ring_type;
+        ring_type const& ring = section.ring_index < 0
+            ? ggl::exterior_ring(polygon)
+            : ggl::interior_rings(polygon)[section.ring_index];
+
+        begin = boost::begin(ring) + section.begin_index;
+        end = boost::begin(ring) + section.end_index + 1;
+    }
+};
+
+} // namespace dispatch
+#endif
+
+
+
+
+/*!
+    \brief Get iterators for a specified section
+    \ingroup sectionalize
+    \tparam Geometry type
+    \tparam Section type of section to get from
+    \param geometry geometry which might be located in the neighborhood
+    \param section structure with section
+    \param begin begin-iterator (const iterator over points of section)
+    \param end end-iterator (const iterator over points of section)
+    \todo Create non-const version as well
+
+ */
+template <typename Geometry, typename Section>
+inline void get_section(Geometry const& geometry, Section const& section,
+    typename boost::range_const_iterator
+        <
+            typename ggl::range_type<Geometry>::type
+        >::type& begin,
+    typename boost::range_const_iterator
+        <
+            typename ggl::range_type<Geometry>::type
+        >::type& end)
+{
+    concept::check<const Geometry>();
+
+    dispatch::get_section
+        <
+            typename tag<Geometry>::type,
+            Geometry,
+            Section
+        >::apply(geometry, section, begin, end);
+}
+
+
+
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_GET_SECTION_HPP
Added: sandbox/ggl/formal_review/boost/ggl/algorithms/intersection.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/algorithms/intersection.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,358 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_INTERSECTION_HPP
+#define GGL_ALGORITHMS_INTERSECTION_HPP
+
+
+#include <boost/mpl/if.hpp>
+
+#include <ggl/core/reverse_dispatch.hpp>
+#include <ggl/geometries/concepts/check.hpp>
+#include <ggl/algorithms/overlay/clip_linestring.hpp>
+#include <ggl/algorithms/overlay/assemble.hpp>
+
+
+
+/*!
+\defgroup intersection intersection: calculate new geometry containing geometries A and B
+\details The intersection of two geometries A and B is the geometry containing
+    all points of A also belonging to B, but no other elements. The so-called
+    clip is an intersection of a geometry with a box.
+\par Source description:
+- OGC: Returns a geometric object that represents the Point set intersection of
+    this geometric object with another Geometry.
+\see http://en.wikipedia.org/wiki/Intersection_(set_theory)
+\note Any intersection can result in no geometry at all
+
+\par Performance
+- 2776 counties of US are intersected with a 100-points ellipse in 1.1 seconds
+(http://trac.osgeo.org/ggl/wiki/Performance#Interesection)
+- 2776 counties of US are clipped in 0.2 seconds
+(http://trac.osgeo.org/ggl/wiki/Performance#Clip)
+
+
+\par Geometries:
+- \b polygon + \b box (clip) -> \b polygon(s)
+\image html svg_intersection_polygon_box.png
+\image html svg_intersection_countries.png
+- \b ring + \b box (clip) -> \b polygon(s)
+\image html svg_intersection_ring_box.png
+- \b ring + \b ring -> \b polygon(s)
+\image html svg_intersection_ring_ring.png
+- \b polygon + \b ring -> \b polygon(s)
+\image html svg_intersection_polygon_ring.png
+- combinations above -> \b ring(s).
+    <i>If the output is an ouput iterator of rings, holes are omitted</i>
+- \b linestring + \b box (clip)
+\image html svg_intersection_roads.png
+
+\par Example:
+Example showing clipping of linestring with box
+\dontinclude doxygen_1.cpp
+\skip example_clip_linestring1
+\line {
+\until }
+\par Example:
+Example showing clipping of vector, outputting vectors, with box
+\dontinclude doxygen_1.cpp
+\skip example_clip_linestring2
+\line {
+\until }
+\par Example:
+Example showing clipping of polygon with box
+\dontinclude doxygen_1.cpp
+\skip example_intersection_polygon1
+\line {
+\until }
+*/
+
+namespace ggl
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace overlay {
+
+
+
+// Specializations for "take_one" for intersection
+// "one" should be the inner one
+
+// for ring and box
+template
+<
+    typename Tag1, typename Geometry1,
+    typename Tag2, typename Geometry2,
+    typename GeometryOut
+>
+struct take_if_1_is_in_2<Tag1, Geometry1, Tag2, Geometry2, GeometryOut, -1>
+{
+    static inline void apply(Geometry1 const& geometry1,
+                Geometry2 const& geometry2,
+                GeometryOut& out
+                )
+    {
+        ggl::convert(geometry1, out);
+    }
+};
+
+
+template
+<
+    typename Geometry1,
+    typename Tag2, typename Geometry2,
+    typename GeometryOut
+>
+struct take_if_1_is_in_2<polygon_tag, Geometry1, Tag2, Geometry2, GeometryOut, -1>
+{
+    static inline void apply(Geometry1 const& geometry1,
+                Geometry2 const& geometry2,
+                GeometryOut& out
+                )
+    {
+        ggl::convert(exterior_ring(geometry1), out);
+    }
+};
+
+
+template
+<
+    typename Geometry, typename GeometryOut, typename Container
+>
+struct add_holes<polygon_tag, Geometry, GeometryOut, Container, -1>
+{
+
+    static inline void apply(Geometry const& geometry,
+                GeometryOut& out,
+                Container const& holes
+                )
+    {
+        std::vector<sortable> v;
+        sort_interior_rings(holes, v, -1);
+
+        // For an intersection, if a ring is containing an inner ring,
+        // take the outer
+
+        std::size_t const n = boost::size(v);
+
+        for (std::size_t i = 0; i < n; i++)
+        {
+            // So, only if no inners:
+            if (v[i].index_of_parent == -1)
+            {
+                typename ggl::point_type<GeometryOut>::type point;
+                ggl::point_on_border(holes[v[i].index], point);
+                if (ggl::within(point, geometry))
+                {
+                    typename ring_type<GeometryOut>::type hole;
+                    ggl::convert(holes[v[i].index], hole);
+                    ggl::interior_rings(out).push_back(hole);
+                }
+            }
+        }
+    }
+};
+
+
+}} // namespace detail::overlay
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+    typename Tag1, typename Tag2, typename Tag3,
+    typename G1, typename G2,
+    typename OutputIterator,
+    typename GeometryOut
+>
+struct intersection_inserter {};
+
+
+template
+<
+    typename Segment1, typename Segment2,
+    typename OutputIterator, typename GeometryOut
+>
+struct intersection_inserter
+    <
+        segment_tag, segment_tag, point_tag,
+        Segment1, Segment2,
+        OutputIterator, GeometryOut
+    >
+{
+    static inline OutputIterator apply(Segment1 const& segment1,
+            Segment2 const& segment2, OutputIterator out)
+    {
+        typedef typename point_type<GeometryOut>::type point_type;
+
+        // Get the intersection point (or two points)
+        segment_intersection_points<point_type> is
+            = strategy::intersection::relate_cartesian_segments
+            <
+                policies::relate::segments_intersection_points
+                    <
+                        Segment1,
+                        Segment2,
+                        segment_intersection_points<point_type>
+                    >
+            >::relate(segment1, segment2);
+        for (int i = 0; i < is.count; i++)
+        {
+            GeometryOut p;
+            ggl::copy_coordinates(is.intersections[i], p);
+            *out = p;
+            out++;
+        }
+        return out;
+    }
+};
+
+
+template
+<
+    typename Linestring, typename Box,
+    typename OutputIterator, typename GeometryOut
+>
+struct intersection_inserter
+    <
+        linestring_tag, box_tag, linestring_tag,
+        Linestring, Box,
+        OutputIterator, GeometryOut
+    >
+{
+    static inline OutputIterator apply(Linestring const& linestring,
+            Box const& box, OutputIterator out)
+    {
+        typedef typename point_type<GeometryOut>::type point_type;
+        strategy::intersection::liang_barsky<Box, point_type> strategy;
+        return detail::intersection::clip_linestring_with_box<GeometryOut>(box, linestring, out, strategy);
+    }
+};
+
+
+template
+<
+    typename Polygon1, typename Polygon2,
+    typename OutputIterator, typename GeometryOut
+>
+struct intersection_inserter
+    <
+        polygon_tag, polygon_tag, polygon_tag,
+        Polygon1, Polygon2,
+        OutputIterator, GeometryOut
+    >
+    : detail::overlay::overlay_and_assemble
+        <Polygon1, Polygon2, OutputIterator, GeometryOut, -1>
+{};
+
+
+
+template
+<
+    typename Polygon, typename Box,
+    typename OutputIterator, typename GeometryOut
+>
+struct intersection_inserter
+<
+    polygon_tag, box_tag, polygon_tag,
+    Polygon, Box,
+    OutputIterator, GeometryOut
+>
+    : detail::overlay::overlay_and_assemble
+        <Polygon, Box, OutputIterator, GeometryOut, -1>
+{};
+
+
+
+template
+<
+    typename GeometryTag1, typename GeometryTag2, typename GeometryTag3,
+    typename Geometry1, typename Geometry2,
+    typename OutputIterator, typename GeometryOut
+>
+struct intersection_inserter_reversed
+{
+    static inline OutputIterator apply(Geometry1 const& g1,
+                Geometry2 const& g2, OutputIterator out)
+    {
+        return intersection_inserter
+            <
+                GeometryTag2, GeometryTag1, GeometryTag3,
+                Geometry2, Geometry1,
+                OutputIterator, GeometryOut
+            >::apply(g2, g1, out);
+    }
+};
+
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+/*!
+    \brief Intersects two geometries
+    \ingroup intersection
+    \details The two input geometries are intersected and the resulting linestring(s),
+    ring(s) or polygon(s) are sent to the specified output operator.
+    \tparam GeometryOut output geometry type, must be specified
+    \tparam Geometry1 first geometry type
+    \tparam Geometry2 second geometry type
+    \tparam OutputIterator output iterator
+    \param geometry1 first geometry
+    \param geometry2 second geometry
+    \param out the output iterator, outputting linestrings or polygons
+    \return the output iterator
+*/
+template
+<
+    typename GeometryOut,
+    typename Geometry1,
+    typename Geometry2,
+    typename OutputIterator
+>
+inline OutputIterator intersection_inserter(Geometry1 const& geometry1,
+            Geometry2 const& geometry2,
+            OutputIterator out)
+{
+    concept::check<const Geometry1>();
+    concept::check<const Geometry2>();
+
+    return boost::mpl::if_c
+        <
+            reverse_dispatch<Geometry1, Geometry2>::type::value,
+            dispatch::intersection_inserter_reversed
+            <
+                typename tag<Geometry1>::type,
+                typename tag<Geometry2>::type,
+                typename tag<GeometryOut>::type,
+                Geometry1,
+                Geometry2,
+                OutputIterator, GeometryOut
+            >,
+            dispatch::intersection_inserter
+            <
+                typename tag<Geometry1>::type,
+                typename tag<Geometry2>::type,
+                typename tag<GeometryOut>::type,
+                Geometry1,
+                Geometry2,
+                OutputIterator, GeometryOut
+            >
+        >::type::apply(geometry1, geometry2, out);
+}
+
+
+} // ggl
+
+
+#endif //GGL_ALGORITHMS_INTERSECTION_HPP
Added: sandbox/ggl/formal_review/boost/ggl/algorithms/intersects.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/algorithms/intersects.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,104 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_INTERSECTS_HPP
+#define GGL_ALGORITHMS_INTERSECTS_HPP
+
+
+/*!
+\defgroup intersects intersects: detect if a geometry self-intersects or if two geometries intersect
+\par Source descriptions:
+- OGC description: Returns 1 (TRUE) if  this geometric object spatially
+    intersects anotherGeometry.
+- OGC: a.Intersects(b) <=> ! a.Disjoint(b)
+\note There are two overloaded versions:
+- with one geometry, detecting self-intersections
+- with two geometries, deferring to disjoint, returning !disjoint
+
+\par Geometries:
+- \b ring
+- \b polygon
+- for two geometries: same is disjoint
+
+\note if one geometry is completely within another geometry, it "intersects"
+
+*/
+
+
+#include <ggl/geometries/concepts/check.hpp>
+
+
+#include <ggl/algorithms/overlay/get_intersection_points.hpp>
+#include <ggl/algorithms/overlay/self_intersection_points.hpp>
+#include <ggl/algorithms/overlay/adapt_turns.hpp>
+#include <ggl/algorithms/overlay/enrich_intersection_points.hpp>
+#include <ggl/algorithms/overlay/traverse.hpp>
+
+#include <ggl/algorithms/disjoint.hpp>
+
+
+
+namespace ggl
+{
+
+/*!
+    \brief Determine if there is at least one intersection
+        (crossing or self-tangency)
+    \note This function can be called for one geometry (self-intersection) and
+        also for two geometries (intersection)
+    \ingroup intersects
+    \tparam Geometry geometry type
+    \param geometry geometry
+    \return true if there are intersections, else false
+ */
+template <typename Geometry>
+inline bool intersects(Geometry const& geometry)
+{
+    concept::check<const Geometry>();
+
+    typedef typename boost::remove_const<Geometry>::type ncg_type;
+
+    typedef std::vector<ggl::detail::intersection::intersection_point
+        <typename ggl::point_type<Geometry>::type> > ip_vector;
+
+    ip_vector ips;
+
+    dispatch::self_intersection_points
+            <
+                typename tag<ncg_type>::type,
+                is_multi<ncg_type>::type::value,
+                ncg_type,
+                ip_vector
+            >::apply(geometry, true, ips);
+    return ips.size() > 0;
+}
+
+
+/*!
+    \brief Determine if there is at least one intersection
+    \ingroup intersects
+    \tparam Geometry1 first geometry type
+    \tparam Geometry2 second geometry type
+    \param geometry1 first geometry
+    \param geometry2 second geometry
+    \return true if there are intersection(s), else false
+ */
+template <typename Geometry1, typename Geometry2>
+inline bool intersects(Geometry1 const& geometry1, Geometry2 const& geometry2)
+{
+    concept::check<const Geometry1>();
+    concept::check<const Geometry2>();
+
+    return ! ggl::disjoint(geometry1, geometry2);
+}
+
+
+
+} // ggl
+
+#endif //GGL_ALGORITHMS_INTERSECTS_HPP
Added: sandbox/ggl/formal_review/boost/ggl/algorithms/length.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/algorithms/length.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,212 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_LENGTH_HPP
+#define GGL_ALGORITHMS_LENGTH_HPP
+
+#include <iterator>
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits.hpp>
+
+
+#include <ggl/core/cs.hpp>
+
+#include <ggl/geometries/concepts/check.hpp>
+
+#include <ggl/algorithms/assign.hpp>
+#include <ggl/algorithms/detail/calculate_null.hpp>
+
+#include <ggl/strategies/distance.hpp>
+#include <ggl/strategies/length_result.hpp>
+
+/*!
+\defgroup length length: calculate length of a linear geometry
+The length algorithm is implemented for the linestring and the multi_linestring
+geometry and results in the length of the linestring. If the points of
+a linestring have coordinates expressed in kilometers,
+the length of the line is expressed in kilometers as well.
+\par Example:
+Example showing length calculation
+\dontinclude doxygen_1.cpp
+\skip example_length_linestring_iterators1
+\line {
+\until }
+*/
+
+namespace ggl
+{
+
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace length {
+
+
+template<typename Segment, typename Strategy>
+struct segment_length
+{
+    static inline typename length_result<Segment>::type apply(
+            Segment const& segment, Strategy const& strategy)
+    {
+        typedef typename point_type<Segment>::type point_type;
+        point_type p1, p2;
+        assign_point_from_index<0>(segment, p1);
+        assign_point_from_index<1>(segment, p2);
+        return strategy.apply(p1, p2);
+    }
+};
+
+/*!
+\brief Internal, calculates length of a linestring using iterator pairs and
+    specified strategy
+\note for_each could be used here, now that point_type is changed by boost
+    range iterator
+*/
+template<typename Range, typename Strategy>
+struct range_length
+{
+    typedef typename length_result<Range>::type return_type;
+
+    static inline return_type apply(
+            Range const& range, Strategy const& strategy)
+    {
+        return_type sum = return_type();
+
+        typedef typename boost::range_const_iterator<Range>::type iterator_type;
+        iterator_type it = boost::begin(range);
+        if (it != boost::end(range))
+        {
+            iterator_type previous = it++;
+            while(it != boost::end(range))
+            {
+                // Add point-point distance using the return type belonging
+                // to strategy
+                sum += strategy.apply(*previous, *it);
+                previous = it++;
+            }
+        }
+
+        return sum;
+    }
+};
+
+}} // namespace detail::length
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename Tag, typename Geometry, typename Strategy>
+struct length : detail::calculate_null
+    <
+        typename length_result<Geometry>::type,
+        Geometry,
+        Strategy
+    >
+{};
+
+
+template <typename Geometry, typename Strategy>
+struct length<linestring_tag, Geometry, Strategy>
+    : detail::length::range_length<Geometry, Strategy>
+{};
+
+
+// RING: length is currently 0; it might be argued that it is the "perimeter"
+
+
+template <typename Geometry, typename Strategy>
+struct length<segment_tag, Geometry, Strategy>
+    : detail::length::segment_length<Geometry, Strategy>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+    \brief Calculate length of a geometry
+    \ingroup length
+    \details The function length returns the length of a geometry, using the
+        default distance-calculation-strategy
+    \param geometry the geometry, being a ggl::linestring, vector,
+        iterator pair, or any other boost compatible range
+    \return the length
+    Example showing length calculation on a vector
+    \dontinclude doxygen_1.cpp
+    \skip example_length_linestring_iterators2
+    \line {
+    \until }
+ */
+template<typename Geometry>
+inline typename length_result<Geometry>::type length(
+        Geometry const& geometry)
+{
+    concept::check<const Geometry>();
+
+    typedef typename point_type<Geometry>::type point_type;
+    typedef typename cs_tag<point_type>::type cs_tag;
+    typedef typename strategy_distance
+        <
+            cs_tag,
+            cs_tag,
+            point_type,
+            point_type
+        >::type strategy_type;
+
+    return dispatch::length
+        <
+            typename tag<Geometry>::type,
+            Geometry,
+            strategy_type
+        >::apply(geometry, strategy_type());
+}
+
+
+/*!
+    \brief Calculate length of a geometry
+    \ingroup length
+    \details The function length returns the length of a geometry,
+        using specified strategy
+    \param geometry the geometry, being a ggl::linestring, vector,
+        iterator pair, or any other boost compatible range
+    \param strategy strategy to be used for distance calculations.
+    \return the length
+    \par Example:
+    Example showing length calculation using iterators
+        and the Vincenty strategy
+    \dontinclude doxygen_1.cpp
+    \skip example_length_linestring_iterators3
+    \line {
+    \until }
+ */
+template<typename Geometry, typename Strategy>
+inline typename length_result<Geometry>::type length(
+        Geometry const& geometry, Strategy const& strategy)
+{
+    concept::check<const Geometry>();
+
+    return dispatch::length
+        <
+            typename tag<Geometry>::type,
+            Geometry,
+            Strategy
+        >::apply(geometry, strategy);
+}
+
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_LENGTH_HPP
Added: sandbox/ggl/formal_review/boost/ggl/algorithms/make.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/algorithms/make.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,138 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_MAKE_HPP
+#define GGL_ALGORITHMS_MAKE_HPP
+
+#include <ggl/algorithms/assign.hpp>
+
+#include <ggl/geometries/concepts/check.hpp>
+
+namespace ggl
+{
+
+/*!
+    \brief Make a geometry
+    \ingroup access
+    \details the Generic Geometry Library uses concepts for all its geometries. Therefore it does not rely
+    on constructors. The "make" functions are object generators creating geometries. There are overloads
+    with two, three, four or six values, which are implemented depending on the geometry specified.
+    \note It does not work with array-point types, like int[2]
+    \tparam G the geometry type
+    \tparam T the coordinate type
+    \return the geometry
+ */
+template <typename Geometry, typename T>
+inline Geometry make(T const& c1, T const& c2)
+{
+    concept::check<Geometry>();
+
+    Geometry geometry;
+    dispatch::assign
+        <
+            typename tag<Geometry>::type,
+            Geometry,
+            ggl::dimension<Geometry>::type::value
+        >::apply(geometry, c1, c2);
+    return geometry;
+}
+
+/*!
+    \brief Make a geometry
+    \ingroup access
+    \return a 3D point
+ */
+template <typename Geometry, typename T>
+inline Geometry make(T const& c1, T const& c2, T const& c3)
+{
+    concept::check<Geometry>();
+
+    Geometry geometry;
+    dispatch::assign
+        <
+            typename tag<Geometry>::type,
+            Geometry,
+            ggl::dimension<Geometry>::type::value
+        >::apply(geometry, c1, c2, c3);
+    return geometry;
+}
+
+template <typename Geometry, typename T>
+inline Geometry make(T const& c1, T const& c2, T const& c3, T const& c4)
+{
+    concept::check<Geometry>();
+
+    Geometry geometry;
+    dispatch::assign
+        <
+            typename tag<Geometry>::type,
+            Geometry,
+            ggl::dimension<Geometry>::type::value
+        >::apply(geometry, c1, c2, c3, c4);
+    return geometry;
+}
+
+
+
+template <typename Geometry, typename Range>
+inline Geometry make(Range const& range)
+{
+    concept::check<Geometry>();
+
+    Geometry geometry;
+    append(geometry, range);
+    return geometry;
+}
+
+
+/*!
+    \brief Create a box with inverse infinite coordinates
+    \ingroup access
+    \details The make_inverse function initialize a 2D or 3D box with large coordinates, the
+    min corner is very large, the max corner is very small
+    \tparam Geometry the geometry type
+    \return the box
+ */
+template <typename Geometry>
+inline Geometry make_inverse()
+{
+    concept::check<Geometry>();
+
+    Geometry geometry;
+    dispatch::assign_inverse
+        <
+            typename tag<Geometry>::type,
+            Geometry
+        >::apply(geometry);
+    return geometry;
+}
+
+/*!
+    \brief Create a geometry with "zero" coordinates
+    \ingroup access
+    \details The make_zero function initializes a 2D or 3D point or box with coordinates of zero
+    \tparam Geometry the geometry type
+    \return the geometry
+ */
+template <typename Geometry>
+inline Geometry make_zero()
+{
+    concept::check<Geometry>();
+
+    Geometry geometry;
+    dispatch::assign_zero
+        <
+            typename tag<Geometry>::type,
+            Geometry
+        >::apply(geometry);
+    return geometry;
+}
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_MAKE_HPP
Added: sandbox/ggl/formal_review/boost/ggl/algorithms/num_points.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/algorithms/num_points.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,146 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_NUM_POINTS_HPP
+#define GGL_ALGORITHMS_NUM_POINTS_HPP
+
+#include <cstddef>
+
+#include <boost/range.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+#include <ggl/core/is_linear.hpp>
+#include <ggl/core/interior_rings.hpp>
+
+#include <ggl/geometries/concepts/check.hpp>
+
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace num_points {
+
+
+template <typename Range>
+struct range_count
+{
+    static inline std::size_t apply(Range const& range)
+    {
+        return boost::size(range);
+    }
+};
+
+template <typename Geometry, std::size_t D>
+struct other_count
+{
+    static inline std::size_t apply(Geometry const& geometry)
+    {
+        return D;
+    }
+};
+
+template <typename Polygon>
+struct polygon_count
+{
+    static inline std::size_t apply(Polygon const& poly)
+    {
+        std::size_t n = boost::size(exterior_ring(poly));
+        typedef typename boost::range_const_iterator
+            <
+                typename interior_type<Polygon>::type
+            >::type iterator;
+
+        for (iterator it = boost::begin(interior_rings(poly));
+             it != boost::end(interior_rings(poly));
+             ++it)
+        {
+            n += boost::size(*it);
+        }
+
+        return n;
+    }
+};
+
+}} // namespace detail::num_points
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename GeometryTag, bool Linear, typename Geometry>
+struct num_points
+{
+};
+
+template <typename GeometryTag, typename Geometry>
+struct num_points<GeometryTag, true, Geometry>
+        : detail::num_points::range_count<Geometry>
+{
+};
+
+template <typename Geometry>
+struct num_points<point_tag, false, Geometry>
+        : detail::num_points::other_count<Geometry, 1>
+{
+};
+
+template <typename Geometry>
+struct num_points<box_tag, false, Geometry>
+        : detail::num_points::other_count<Geometry, 4>
+{
+};
+
+template <typename Geometry>
+struct num_points<segment_tag, false, Geometry>
+        : detail::num_points::other_count<Geometry, 2>
+{
+};
+
+
+template <typename Geometry>
+struct num_points<polygon_tag, false, Geometry>
+        : detail::num_points::polygon_count<Geometry>
+{
+};
+
+} // namespace dispatch
+#endif
+
+
+/*!
+    \brief get number of points
+    \ingroup access
+    \tparam Geometry geometry type
+    \param geometry the geometry to get number of points from
+    \return number of points
+    \note For linestrings/rings also boost::size or .size() could be used, however,
+        for polygons this is less obvious. So this function is provided. Besides that
+        it is described by OGC (numPoints)
+*/
+template <typename Geometry>
+inline std::size_t num_points(Geometry const& geometry)
+{
+    concept::check<const Geometry>();
+
+    typedef typename boost::remove_const<Geometry>::type ncg_type;
+
+    return dispatch::num_points
+        <
+            typename tag<Geometry>::type,
+            is_linear<ncg_type>::value,
+            ncg_type
+        >::apply(geometry);
+}
+
+}
+
+
+#endif // GGL_ALGORITHMS_NUM_POINTS_HPP
Added: sandbox/ggl/formal_review/boost/ggl/algorithms/overlaps.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/algorithms/overlaps.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,193 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_OVERLAPS_HPP
+#define GGL_ALGORITHMS_OVERLAPS_HPP
+
+/*!
+\defgroup overlaps overlaps: detect overlap between two geometries
+\par Source descriptions:
+- Egenhofer: Two objects overlap if they have common interior faces and the bounding faces have common parts
+with the opposite interior faces.
+
+\par Geometries:
+- \b box + \b box
+
+*/
+
+
+#include <ggl/core/access.hpp>
+
+#include <ggl/geometries/concepts/check.hpp>
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace overlaps {
+
+template
+<
+    typename Box1,
+    typename Box2,
+    std::size_t Dimension,
+    std::size_t DimensionCount
+>
+struct box_box_loop
+{
+    static inline void apply(Box1 const& b1, Box2 const& b2,
+            bool& overlaps, bool& one_in_two, bool& two_in_one)
+    {
+        assert_dimension_equal<Box1, Box2>();
+
+        typedef typename coordinate_type<Box1>::type coordinate_type1;
+        typedef typename coordinate_type<Box2>::type coordinate_type2;
+
+        coordinate_type1 const& min1 = get<min_corner, Dimension>(b1);
+        coordinate_type1 const& max1 = get<max_corner, Dimension>(b1);
+        coordinate_type2 const& min2 = get<min_corner, Dimension>(b2);
+        coordinate_type2 const& max2 = get<max_corner, Dimension>(b2);
+
+        // We might use the (not yet accepted) Boost.Interval
+        // submission in the future
+
+        // If:
+        // B1: |-------|
+        // B2:           |------|
+        // in any dimension -> no overlap
+        if (max1 <= min2 || min1 >= max2)
+        {
+            overlaps = false;
+            return;
+        }
+
+        // If:
+        // B1: |--------------------|
+        // B2:   |-------------|
+        // in all dimensions -> within, then no overlap
+        // B1: |--------------------|
+        // B2: |-------------|
+        // this is "within-touch" -> then no overlap. So use < and >
+        if (min1 < min2 || max1 > max2)
+        {
+            one_in_two = false;
+        }
+        // Same other way round
+        if (min2 < min1 || max2 > max1)
+        {
+            two_in_one = false;
+        }
+
+        box_box_loop
+            <
+                Box1,
+                Box2,
+                Dimension + 1,
+                DimensionCount
+            >::apply(b1, b2, overlaps, one_in_two, two_in_one);
+    }
+};
+
+template
+<
+    typename Box1,
+    typename Box2,
+    std::size_t DimensionCount
+>
+struct box_box_loop<Box1, Box2, DimensionCount, DimensionCount>
+{
+    static inline void apply(Box1 const& , Box2 const&, bool&, bool&, bool&)
+    {
+    }
+};
+
+template
+<
+    typename Box1,
+    typename Box2
+>
+struct box_box
+{
+    static inline bool apply(Box1 const& b1, Box2 const& b2)
+    {
+        bool overlaps = true;
+        bool within1 = true;
+        bool within2 = true;
+        box_box_loop
+            <
+                Box1,
+                Box2,
+                0,
+                dimension<Box1>::type::value
+            >::apply(b1, b2, overlaps, within1, within2);
+
+        /*
+        \see http://docs.codehaus.org/display/GEOTDOC/02+Geometry+Relationships#02GeometryRelationships-Overlaps
+        where is stated that "inside" is not an "overlap",
+        this is true and is implemented as such.
+        */
+        return overlaps && ! within1 && ! within2;
+    }
+};
+
+
+
+}} // namespace detail::overlaps
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+    typename Tag1,
+    typename Tag2,
+    typename Geometry1,
+    typename Geometry2
+>
+struct overlaps
+{};
+
+
+template <typename Box1, typename Box2>
+struct overlaps<box_tag, box_tag, Box1, Box2>
+    : detail::overlaps::box_box<Box1, Box2>
+{};
+
+
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+    \brief Determines overlap between two geometries
+    \ingroup overlaps
+    \return true if there is overlap
+ */
+template <typename Geometry1, typename Geometry2>
+inline bool overlaps(Geometry1 const& geometry1, Geometry2 const& geometry2)
+{
+    concept::check<const Geometry1>();
+    concept::check<const Geometry2>();
+
+    return dispatch::overlaps
+        <
+            typename tag<Geometry1>::type,
+            typename tag<Geometry2>::type,
+            Geometry1,
+            Geometry2
+        >::apply(geometry1, geometry2);
+}
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_OVERLAPS_HPP
Added: sandbox/ggl/formal_review/boost/ggl/algorithms/overlay/adapt_turns.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/algorithms/overlay/adapt_turns.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,549 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_OVERLAY_ADAPT_TURNS_HPP
+#define GGL_ALGORITHMS_OVERLAY_ADAPT_TURNS_HPP
+
+#include <algorithm>
+
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+
+#include <ggl/core/coordinate_type.hpp>
+
+#include <ggl/strategies/side.hpp>
+
+#include <ggl/algorithms/equals.hpp>
+
+
+namespace ggl
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace intersection {
+
+
+template <typename T>
+inline void join_adapt(T& info, int direction)
+{
+    info.first->direction = direction;
+    info.second->direction = direction;
+}
+
+
+template <typename T>
+inline void both_same(T const& pi, T & pk, T const& qu, T& qw, int dir_p, int dir_q, int direction)
+{
+    // Comments are for "both Left"
+    if (dir_q == direction) // If (Qw left-of Qu)
+    {
+        if (dir_p == -direction) // if (Pk right-of Pi)
+        {
+            // make Pk Right, Qw Left
+            join_adapt(pk, -direction);
+            join_adapt(qw, direction);
+        }
+        else if (pk.first->direction == -direction) // else if (Pk right-of Qu)
+        {
+            // make both Right
+            join_adapt(pk, -direction);
+            join_adapt(qw, -direction);
+        }
+    }
+    else
+    {
+        if (dir_p == -direction // if (Pk right-of Pi
+            || pk.first->direction == direction) // || Pk left-of Qu)
+        {
+            //  make both Left
+            join_adapt(pk, direction);
+            join_adapt(qw, direction);
+        }
+    }
+}
+
+
+template <typename T>
+inline void crossing(T const& pi, T & pk, T const& qu, T& qw, int dir_p, int dir_q, int direction)
+{
+    if (dir_p == direction) // If (Pk left-of Pi)
+    {
+        if (pk.first->direction == -direction) // if (Pk right-of Qu)
+        {
+            // make both Right
+            join_adapt(pk, -direction);
+            join_adapt(qw, -direction);
+        }
+        else
+        {
+            // make Pk Left, Qw Right
+            join_adapt(pk, direction);
+            join_adapt(qw, -direction);
+        }
+    }
+}
+
+
+template <typename T>
+inline void collinear(T const& pi, T & pk, T const& qu, T& qw, int dir_p, int dir_q, int direction)
+{
+    if (dir_p == direction // If (Pk left-of Pi
+        && dir_q == direction // && Qw left-of Qu
+        && pk.first->direction == -direction) // && Pk right-of Qu
+    {
+        // make both Right
+        join_adapt(pk, -direction);
+        join_adapt(qw, -direction);
+    }
+    else if (dir_p == -direction // If (Pk right-of Pi
+        && dir_q == -direction) // && Qw right-of Qu
+    {
+        // make both Left
+        join_adapt(pk, direction);
+        join_adapt(qw, direction);
+    }
+
+}
+
+
+template <typename T, typename P>
+inline void assign_pq(T const& info, P& p, P& q)
+{
+    if (info.seg_id.source_index == 0)
+    {
+        if (info.arrival == 1)
+        {
+            p.first = info.other_point;
+        }
+        else if (info.arrival == -1)
+        {
+            p.second = info.other_point;
+        }
+    }
+    else
+    {
+        if (info.arrival == 1)
+        {
+            q.first = info.other_point;
+        }
+        else if (info.arrival == -1)
+        {
+            q.second = info.other_point;
+        }
+    }
+}
+
+
+template <typename Info, typename Point>
+inline void touch_in_the_middle(Info& info, Point const& point)
+{
+    typedef typename boost::range_iterator<Info>::type iterator;
+
+    // Determine which is Q, and assign points
+    iterator qu, qw, p;
+    int count = 0;
+
+    // Find out which one is arriving/departing from the middle
+    for (iterator it = boost::begin(info);
+        it != boost::end(info);
+        ++it)
+    {
+        // One arrives AND departs in the middle of the other.
+        if(it->how == 'm' && it->arrival == 1)
+        {
+            qu = it;
+            count |= 1;
+        }
+        else if(it->how == 's' && it->arrival == -1)
+        {
+            qw = it;
+            count |= 2;
+        }
+        else if (it->how == 's') //  or m, does not really matter
+        {
+            p = it;
+            count |= 4;
+        }
+
+    }
+    // Adapt it
+    if (count == 7
+        && qu->direction == qw->direction
+        && qu->seg_id.source_index == qw->seg_id.source_index)
+    {
+        typedef typename strategy_side
+            <
+                typename cs_tag<Point>::type
+            >::type side;
+
+
+        int dir_q = side::apply(qu->other_point, point, qw->other_point);
+
+#ifdef GGL_DEBUG_INTERSECTION
+        std::cout << "Both "
+            << (qu->direction == 1 ? "Left" : "Right")
+            << ", Turn " << (dir_q == 1 ? "Left" : dir_q == -1 ? "Right" : "?")
+            << std::endl;
+#endif
+
+        // Let P also be starting
+        p->arrival = -1;
+
+        // This is also symmetric. See slides:
+        // Qu left-of P && Qw left-of P
+        if (qu->direction == 1 && dir_q == -1)
+        {
+            // make both Left
+            p->direction = 1;
+            qw->direction = 1;
+        }
+        // else, symmetric version
+        else if (qu->direction == -1 && dir_q == 1)
+        {
+            p->direction = -1;
+            qw->direction = -1;
+        }
+    }
+}
+
+
+template <typename Info>
+inline void arrive_in_the_middle(Info& info)
+{
+    typedef typename boost::range_iterator<Info>::type iterator;
+
+    // Find out which one is NOT arriving in the middle,
+    // and the direction of the one arriving in the middle
+    int departing = -1;
+    int direction = 0;
+    for (iterator it = boost::begin(info);
+        it != boost::end(info);
+        ++it)
+    {
+        if(it->how == 'm')
+        {
+            switch(it->arrival)
+            {
+                case 1 : direction = it->direction; break;
+                default : departing = it->seg_id.source_index;
+            }
+        }
+    }
+
+    // Make this the departing one, following collinear in opposite segment,
+    // same direction as established above
+    for (iterator it = boost::begin(info);
+        it != boost::end(info);
+        ++it)
+    {
+        if (it->how == 'c' && it->seg_id.source_index == departing)
+        {
+            it->arrival = -1;
+            it->direction = direction;
+        }
+    }
+}
+
+
+template <typename Info>
+inline void start_in_the_middle(Info& info, bool opposite)
+{
+    typedef typename boost::range_iterator<Info>::type iterator;
+
+    for (iterator it = boost::begin(info);
+        it != boost::end(info);
+        ++it)
+    {
+        if(it->how == 's')
+        {
+            if (! opposite)
+            {
+                // Not opposite, all "start" traversals can also be made "departing"
+                it->arrival = -1;
+            }
+            else if (opposite && it->arrival == 0)
+            {
+                // Prevent the collinear the "start" from "departing",
+                // if it is in opposite direction
+                it->arrival = 1;
+                it->direction = 0;
+                it->flagged = true; // might be deleted
+            }
+        }
+    }
+}
+
+
+template <typename V>
+inline void adapt_turns(V& intersection_points)
+{
+    typedef typename boost::range_iterator<V>::type iterator_type;
+    typedef typename boost::range_value<V>::type ip_type;
+    typedef typename ip_type::traversal_type info_type;
+
+    typedef typename boost::range_value<V>::type::traversal_vector vector_type;
+    typedef typename boost::range_iterator<vector_type>::type tvit_type;
+
+    for (iterator_type it = boost::begin(intersection_points);
+         it != boost::end(intersection_points);
+         ++it)
+    {
+        if (! it->trivial)
+        {
+            if (boost::size(it->info) == 4)
+            {
+                /*
+                    can be ARRIVE/START from the middle (#11)
+                        src 0 seg 1 (// 1.0) how m[A R] p // qu
+                        src 0 seg 1 (// 1.1) how s[D L] p // qw
+                        src 1 seg 0 (// 0.1) how m[A R] qu / p
+                        src 1 seg 1 (// 0.1) how s[D R] qw / p
+
+                    or can be ARRIVE at COLLINEARITY (#8, #13)
+                        src 0 seg 1 (// 1.1) how m[A L] p // qu
+                        src 0 seg 1 (// 1.2) how c[- -] p // qw
+                        src 1 seg 1 (// 0.1) how m[A L] qu // p
+                        src 1 seg 2 (// 0.1) how c[- -] qw // p
+
+                    or can be START from COLLINEARITY (#8, #13)
+                        src 0 seg 1 (// 1.2) how c[- -] p // qu
+                        src 0 seg 1 (// 1.0) how s[D R] p // qw
+                        src 1 seg 2 (// 0.1) how c[- -] qu // p
+                        src 1 seg 0 (// 0.1) how s[D L] qw // p
+                */
+
+                 // First detect the case and if it is opposite
+                int count_m = 0, count_s = 0, count_c = 0;
+
+                bool opposite = false;
+                for (tvit_type tvit = boost::begin(it->info);
+                    tvit != boost::end(it->info);
+                    ++tvit)
+                {
+                    switch(tvit->how)
+                    {
+                        case 'm' : count_m++; break;
+                        case 's' : count_s++; break;
+                        case 'c' : count_c++; break;
+                    }
+                    if (tvit->opposite)
+                    {
+                        opposite = true;
+                    }
+                }
+
+                if (count_m == 2 && count_s == 2)
+                {
+#ifdef GGL_DEBUG_INTERSECTION
+                    std::cout << "Touching the middle " << std::endl;
+#endif
+
+                    touch_in_the_middle(it->info, it->point);
+                }
+                else if (count_m == 2 && count_c == 2 && opposite)
+                {
+#ifdef GGL_DEBUG_INTERSECTION
+                    std::cout << "Arriving the middle/collinearity, opposite" << std::endl;
+#endif
+
+                    arrive_in_the_middle(it->info);
+                }
+                else if (count_s == 2 && count_c == 2)
+                {
+#ifdef GGL_DEBUG_INTERSECTION
+                    std::cout << "Starting from middle/collinearity"
+                        << (opposite ? " , opposite"  : "")
+                        << std::endl;
+#endif
+
+                    start_in_the_middle(it->info, opposite);
+                }
+            }
+
+            if (boost::size(it->info) == 8)
+            {
+                /*
+                  src 0 seg 1 (// 1.0) how t[A R]   pi // qu   pi.first
+                  src 0 seg 1 (// 1.1) how a[A R]   pi // qw   pi.second
+                  src 0 seg 2 (// 1.0) how a[D R]   pk // qu   pk.first
+                  src 0 seg 2 (// 1.1) how f[D L]   pk // qw   pk.second
+
+                  src 1 seg 0 (// 0.1) how t[A L]   qu // pi
+                  src 1 seg 0 (// 0.2) how a[A R]   qu // pk
+                  src 1 seg 1 (// 0.1) how a[D R]   qw // pi
+                  src 1 seg 1 (// 0.2) how f[D R]   qw // pk
+                */
+
+                std::pair<tvit_type, tvit_type> pi, pk, qu, qw;
+                std::pair<typename info_type::point_type, typename info_type::point_type> p, q;
+
+
+                // Find out which is which
+                for (tvit_type tvit = boost::begin(it->info);
+                    tvit != boost::end(it->info);
+                    ++tvit)
+                {
+                    assign_pq(*tvit, p, q);
+                    if (tvit->seg_id.source_index == 0)
+                    {
+                        if (tvit->arrival == 1)
+                        {
+                            if(tvit->how != 'a')
+                            {
+                                pi.first = tvit;
+                            }
+                            else
+                            {
+                                pi.second = tvit;
+                            }
+
+                        }
+                        else if (tvit->arrival == -1)
+                        {
+                            if (tvit->how == 'a')
+                            {
+                                pk.first = tvit;
+                            }
+                            else
+                            {
+                                pk.second = tvit;
+                            }
+                        }
+                    }
+                    else
+                    {
+                        if (tvit->arrival == 1)
+                        {
+                            if(tvit->how != 'a')
+                            {
+                                qu.first = tvit;
+                            }
+                            else
+                            {
+                                qu.second = tvit;
+                            }
+                        }
+                        else if (tvit->arrival == -1)
+                        {
+                            if (tvit->how == 'a')
+                            {
+                                qw.first = tvit;
+                            }
+                            else
+                            {
+                                qw.second = tvit;
+                            }
+                        }
+                    }
+                }
+
+                typedef typename strategy_side
+                    <
+                        typename cs_tag<ip_type>::type
+                    >::type side;
+
+
+                int dir_p = side::apply(p.first, it->point, p.second);
+                int dir_q = side::apply(q.first, it->point, q.second);
+
+#ifdef GGL_DEBUG_INTERSECTION
+                std::cout << "Pi//Qu : " << *pi.first << std::endl;
+                std::cout << "Pi//Qw : " << *pi.second << std::endl;
+                std::cout << "Pk//Qu : " << *pk.first << std::endl;
+                std::cout << "Pk//Qw : " << *pk.second << std::endl;
+                std::cout << "Qu//Pi : " << *qu.first << std::endl;
+                std::cout << "Qu//Pk : " << *qu.second << std::endl;
+                std::cout << "Qw//Pi : " << *qw.first << std::endl;
+                std::cout << "Qw//Pk : " << *qw.second << std::endl;
+                if (dir_p == 1) std::cout << "P turns left" << std::endl;
+                if (dir_p == -1) std::cout << "P turns right" << std::endl;
+                if (dir_q == 1) std::cout << "Q turns left" << std::endl;
+                if (dir_q == -1) std::cout << "Q turns right" << std::endl;
+#endif
+
+                if (qu.first->direction == qw.first->direction)
+                {
+                    // Both Right or Both Left
+#ifdef GGL_DEBUG_INTERSECTION
+                    std::cout << "Both "
+                        << (qu.first->direction == 1 ? "Left" : "Right")
+                        << std::endl;
+#endif
+
+                    both_same(pi, pk, qu, qw, dir_p, dir_q, qu.first->direction);
+                }
+                else if (qu.first->direction == -qw.first->direction)
+                {
+                    // From Left to Right, or from Right to Left
+#ifdef GGL_DEBUG_INTERSECTION
+                    std::cout << "Left to/from Right" << std::endl;
+#endif
+                    crossing(pi, pk, qu, qw, dir_p, dir_q, qu.first->direction);
+                }
+                else if (qw.first->direction == 1 || qu.first->direction == 1)
+                {
+                    // Collinear left
+#ifdef GGL_DEBUG_INTERSECTION
+                    std::cout << "Collinear left" << std::endl;
+#endif
+                    collinear(pi, pk, qu, qw, dir_p, dir_q, 1);
+                }
+                else if (qw.first->direction == -1 || qu.first->direction == -1)
+                {
+                    // Collinear right
+#ifdef GGL_DEBUG_INTERSECTION
+                    std::cout << "Collinear right" << std::endl;
+#endif
+                    collinear(pi, pk, qu, qw, dir_p, dir_q, -1);
+                }
+
+
+                for (tvit_type tvit = boost::begin(it->info);
+                    tvit != boost::end(it->info);
+                    ++tvit)
+                {
+                    if (tvit->how == 'a')
+                    {
+                        tvit->direction = 0;
+                    }
+                }
+             }
+        }
+    }
+
+#ifdef GGL_DEBUG_INTERSECTION
+    std::cout << "Adapted turns: " << std::endl;
+    report_ip(intersection_points);
+#endif
+}
+
+
+}} // namespace detail::intersection
+#endif //DOXYGEN_NO_DETAIL
+
+
+template <typename V>
+inline void adapt_turns(V& intersection_points)
+{
+    // If there are merges, there might be merged IP's which have right turns
+    detail::intersection::adapt_turns(intersection_points);
+
+#ifdef GGL_DEBUG_INTERSECTION
+    std::cout << "Merged (2): " << std::endl;
+    report_ip(intersection_points);
+#endif
+
+}
+
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_OVERLAY_ADAPT_TURNS_HPP
Added: sandbox/ggl/formal_review/boost/ggl/algorithms/overlay/assemble.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/algorithms/overlay/assemble.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,471 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_OVERLAY_ASSEMBLE_HPP
+#define GGL_ALGORITHMS_OVERLAY_ASSEMBLE_HPP
+
+
+#include <deque>
+
+#include <ggl/algorithms/overlay/get_intersection_points.hpp>
+#include <ggl/algorithms/overlay/merge_intersection_points.hpp>
+#include <ggl/algorithms/overlay/adapt_turns.hpp>
+#include <ggl/algorithms/overlay/enrich_intersection_points.hpp>
+#include <ggl/algorithms/overlay/traverse.hpp>
+#include <ggl/algorithms/overlay/sort_interior_rings.hpp>
+
+
+#include <ggl/algorithms/convert.hpp>
+#include <ggl/algorithms/num_points.hpp>
+#include <ggl/algorithms/within.hpp>
+
+#include <ggl/algorithms/detail/point_on_border.hpp>
+
+#include <ggl/iterators/range_type.hpp>
+
+namespace ggl
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace overlay {
+
+
+// Utility function
+template <typename GeometryOut, typename Geometry, typename OutputIterator>
+void convert_and_output(Geometry const& geometry, OutputIterator& out)
+{
+    // How can we avoid the double copy here! It is really bad!
+    // We have to create a polygon, then copy it to the output iterator.
+    // Having an output-vector would have been better: append it to the vector!
+    // So output iterators are not that good.
+
+    GeometryOut result;
+    ggl::convert(geometry, result);
+    *out = result;
+    out++;
+}
+
+
+
+
+template
+<
+    typename Tag1, typename Geometry1,
+    typename Tag2, typename Geometry2, typename GeometryOut,
+    int Direction
+>
+struct take_if_1_is_in_2
+{};
+
+
+template
+<
+    int Direction,
+    typename Geometry1, typename Geometry2, typename GeometryOut
+>
+inline bool take_one(Geometry1 const& geometry1,
+            Geometry2 const& geometry2,
+            GeometryOut& out
+            )
+{
+    typename ggl::point_type<Geometry1>::type point;
+    ggl::point_on_border(geometry1, point);
+    if (ggl::within(point, geometry2))
+    {
+        take_if_1_is_in_2
+            <
+                typename tag<Geometry1>::type, Geometry1,
+                typename tag<Geometry2>::type, Geometry2,
+                GeometryOut, Direction
+            >::apply(geometry1, geometry2, out);
+        return true;
+    }
+    return false;
+}
+
+
+template
+<
+    typename TagOut,
+    typename Geometry, typename GeometryOut,
+    typename Container,
+    int Direction
+>
+struct add_holes
+{
+    static inline void apply(Geometry const&, GeometryOut&, Container const& holes)
+    {}
+};
+
+
+
+template
+<
+    typename Geometry1, typename Geometry2,
+    typename OutputIterator, typename GeometryOut,
+    int Direction
+>
+struct take_none_or_both
+{
+    static inline void apply(Geometry1 const& geometry1,
+                Geometry2 const& geometry2,
+                OutputIterator out
+                )
+    {
+    }
+
+};
+
+
+template
+<
+    typename Tag, typename GeometryOut,
+    typename Container, int Direction
+>
+struct assemble_rings
+{
+    template <typename OutputIterator>
+    static inline void apply(Container const& rings,
+                Container const& ni_holes,
+                OutputIterator out)
+    {}
+};
+
+
+template
+<
+    typename GeometryOut, typename Container, int Direction
+>
+struct assemble_rings<polygon_tag, GeometryOut, Container, Direction>
+{
+    typedef typename boost::range_value<Container>::type ring_type;
+    typedef typename ggl::point_type<ring_type>::type point_type;
+
+    template <typename OutputIterator>
+    static inline void apply(Container const& rings,
+                Container const& ni_holes,
+                OutputIterator out)
+    {
+        std::vector<sortable> sorted_rings;
+        sort_interior_rings(rings, sorted_rings, 1);
+
+        // Add polygons, and holes
+        for (std::vector<sortable>::const_iterator
+                rit = boost::begin(sorted_rings);
+            rit != boost::end(sorted_rings);
+            ++rit)
+        {
+            if (rit->index_of_parent == -1)
+            {
+                GeometryOut result;
+                ggl::convert(rings[rit->index], result);
+
+                // Add holes (direction is OK, so no reverse)
+                std::vector<int> const& holes = rit->index_of_holes;
+                for (std::vector<int>::const_iterator hit = holes.begin();
+                        hit != holes.end();
+                        ++hit)
+                {
+                    interior_rings(result).push_back(rings[*hit]);
+                }
+
+                // Add also all non-intersecting-inner-holes
+                add_holes
+                    <
+                        polygon_tag,
+                        ring_type, GeometryOut, Container,
+                        Direction
+                    >::apply(rings[rit->index], result, ni_holes);
+
+                *out = result;
+                out++;
+            }
+        }
+    }
+};
+
+
+template
+<
+    typename GeometryOut, typename Container, int Direction
+>
+struct assemble_rings<ring_tag, GeometryOut, Container, Direction>
+{
+    typedef typename boost::range_value<Container>::type ring_type;
+    typedef typename ggl::point_type<ring_type>::type point_type;
+
+    template <typename OutputIterator>
+    static inline void apply(Container const& rings,
+                Container const& ni_holes,
+                OutputIterator out)
+    {
+        // Add positive rings, ignore all holes
+        for (typename boost::range_const_iterator<Container>::type
+            it = boost::begin(rings);
+            it != boost::end(rings);
+            ++it)
+        {
+            if (ggl::area(*it) > 0)
+            {
+                convert_and_output<GeometryOut>(*it, out);
+            }
+        }
+    }
+};
+
+
+
+template<typename Tag>
+struct get_not_intersecting_holes
+{
+    template
+    <
+        typename Polygon,
+        typename IpContainer, typename HoleContainer
+    >
+    static inline void apply(Polygon const&, int,
+        IpContainer const&, HoleContainer& )
+    {
+    }
+};
+
+
+template<>
+struct get_not_intersecting_holes<polygon_tag>
+{
+    template
+    <
+        typename Polygon,
+        typename IpContainer, typename HoleContainer
+    >
+    static inline void apply(Polygon const& polygon, int source_index,
+        IpContainer const& ips,
+        HoleContainer& holes)
+    {
+        typedef typename boost::range_value<IpContainer>::type ip_type;
+        typedef typename boost::range_const_iterator<IpContainer>::type iterator_type;
+        typedef typename ip_type::traversal_vector vector_type;
+        typedef typename boost::range_const_iterator<vector_type>::type tvit_type;
+
+        // Declare vector, fill with false
+        int const n = num_interior_rings(polygon);
+        std::vector<bool> intersecting(n, false);
+
+
+        // Check all IP's and set corresponding inner rings to "intersecting"
+        for (iterator_type it = boost::begin(ips);
+            it != boost::end(ips);
+            ++it)
+        {
+           for (tvit_type tvit = boost::begin(it->info);
+                tvit != boost::end(it->info);
+                ++tvit)
+            {
+                if (tvit->seg_id.source_index == source_index)
+                {
+                    int const r = tvit->seg_id.ring_index;
+                    if (r >= 0 && r < n)
+                    {
+                        intersecting[r] = true;
+                    }
+                }
+            }
+        }
+
+        typename boost::range_const_iterator
+                <
+                    typename interior_type<Polygon>::type
+                >::type rit = boost::begin(interior_rings(polygon));
+        std::vector<bool>::const_iterator iit = boost::begin(intersecting);
+
+        for (;
+            rit != boost::end(interior_rings(polygon))
+            && iit != boost::end(intersecting);
+             ++rit, ++iit)
+        {
+            if (! (*iit))
+            {
+                // Don't pushback, it might be of different type.
+                holes.resize(holes.size() + 1);
+                ggl::convert(*rit, holes.back());
+            }
+        }
+    }
+};
+
+
+
+template
+<
+    typename Geometry1, typename Geometry2,
+    typename OutputIterator, typename GeometryOut,
+    int Direction
+>
+struct overlay_and_assemble
+{
+    typedef typename ggl::tag<Geometry1>::type tag1;
+    typedef typename ggl::tag<Geometry2>::type tag2;
+    typedef typename ggl::tag<GeometryOut>::type tag_out;
+
+    static inline OutputIterator apply(Geometry1 const& geometry1,
+                Geometry2 const& geometry2, OutputIterator out)
+    {
+        if (ggl::num_points(geometry1) == 0
+            || ggl::num_points(geometry2) == 0)
+        {
+            return out;
+        }
+
+
+        typedef typename ggl::point_type<GeometryOut>::type point_type;
+        typedef detail::intersection::intersection_point<point_type> ip_type;
+        typedef std::deque<ip_type> container_type;
+
+        // "Abuse" rangetype for ringtype: for polygon, it is the type of the
+        // exterior ring. For ring, it is the ring itself. That is what is
+        // wished here as well.
+        typedef typename ggl::range_type<GeometryOut>::type ring_type;
+
+        container_type ips; // intersection points
+
+        bool trivial = ggl::get_intersection_points(geometry1, geometry2, ips);
+
+        // If there are no IP-s, check if one point is in other geometry
+        // (both geometries have points, see check above)
+        // If yes, take the correct one
+
+        // (which depends on intersection/union)
+        // If both are unrelated, take none (intersection) or both (union)
+
+        // If there are disjoint or containing holes:
+        // - Hole of A can be within hole of B
+        //   - for union: take hole of A
+        //   - for intersection: take hole of B
+        // - Hole of A can be disjoint from B
+        //   - for union: remove those holes
+        //   - for intersection: take all those holes
+        // -> generic procedure
+        // - Collect all holes in one vector
+        // - Sort them on decreasing area
+        // - Check if one is within a larger one,
+        //   - if yes, take one of them
+        //   - if no, take all, or none of them
+
+        // Gather non-intersecting holes
+        typedef std::vector<ring_type> hole_vector_type;
+        hole_vector_type ni_holes;
+        get_not_intersecting_holes<tag1>::apply(geometry1, 0, ips, ni_holes);
+        get_not_intersecting_holes<tag2>::apply(geometry2, 1, ips, ni_holes);
+
+        if (ips.size() <= 0)
+        {
+            GeometryOut result;
+            if (take_one<Direction>(geometry1, geometry2, result))
+            {
+                add_holes
+                    <
+                        tag_out, Geometry1, GeometryOut, hole_vector_type,
+                        Direction
+                    >::apply(geometry1, result, ni_holes);
+                *out = result;
+                out++;
+            }
+            else if (take_one<Direction>(geometry2, geometry1, result))
+            {
+                add_holes
+                    <
+                        tag_out,
+                        Geometry2, GeometryOut, hole_vector_type,
+                        Direction
+                    >::apply(geometry2, result, ni_holes);
+                *out = result;
+                out++;
+            }
+            else
+            {
+                take_none_or_both
+                    <
+                        Geometry1, Geometry2,
+                        OutputIterator, GeometryOut,
+                        Direction
+                    >::apply(geometry1, geometry2, out);
+            }
+        }
+        else
+        {
+            if (! trivial)
+            {
+                ggl::merge_intersection_points(ips);
+
+                // If all IP's are removed, they are all collinear or forming
+                // an angle which each other.
+                // In that case, the inputs are EQUAL.
+                // For both intersection and union, just output one.
+                if (ips.size() == 0)
+                {
+                    convert_and_output<GeometryOut>(geometry1, out);
+                    return out;
+                }
+
+                ggl::adapt_turns(ips);
+            }
+
+            ggl::enrich_intersection_points(ips, trivial);
+
+
+            std::vector<ring_type> v;
+            ggl::traverse<ring_type>
+                (
+                    geometry1,
+                    geometry2,
+                    Direction,
+                    ips,
+                    trivial,
+                    std::back_inserter(v)
+                );
+
+            switch (boost::size(v))
+            {
+                case 0 : break;
+                case 1 :
+                    //convert_and_output<GeometryOut>(v.front(), out);
+                    {
+                        GeometryOut result;
+                        ggl::convert(v.front(), result);
+                        add_holes
+                            <
+                                tag_out,
+                                ring_type, GeometryOut, hole_vector_type,
+                                Direction
+                            >::apply(v.front(), result, ni_holes);
+                        *out = result;
+                        out++;
+                    }
+                    break;
+                default :
+                    assemble_rings
+                        <
+                            tag_out, GeometryOut,
+                            hole_vector_type, Direction
+                        >::apply(v, ni_holes, out);
+            }
+        }
+
+        return out;
+    }
+};
+
+
+}} // namespace detail::overlay
+#endif // DOXYGEN_NO_DETAIL
+
+
+} // ggl
+
+#endif //GGL_ALGORITHMS_OVERLAY_ASSEMBLE_HPP
Added: sandbox/ggl/formal_review/boost/ggl/algorithms/overlay/clip_linestring.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/algorithms/overlay/clip_linestring.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,238 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_OVERLAY_CLIP_LINESTRING_HPP
+#define GGL_ALGORITHMS_OVERLAY_CLIP_LINESTRING_HPP
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/algorithms/append.hpp>
+#include <ggl/algorithms/clear.hpp>
+#include <ggl/util/copy.hpp>
+#include <ggl/util/select_coordinate_type.hpp>
+#include <ggl/geometries/segment.hpp>
+
+namespace ggl
+{
+
+namespace strategy { namespace intersection {
+
+/*!
+    \brief Strategy: line clipping algorithm after Liang Barsky
+    \ingroup overlay
+    \details The Liang-Barsky line clipping algorithm clips a line with a clipping box.
+    It is slightly adapted in the sense that it returns which points are clipped
+    \tparam B input box type of clipping box
+    \tparam P input/output point-type of segments to be clipped
+    \note The algorithm is currently only implemented for 2D Cartesian points
+    \note Though it is implemented in namespace strategy, and theoretically another
+        strategy could be used, it is not (yet) updated to the general strategy concepts,
+        and not (yet) splitted into a file in folder strategies
+    \author Barend Gehrels, and the following recourses
+    - A tutorial: http://www.skytopia.com/project/articles/compsci/clipping.html
+    - a German applet (link broken): http://ls7-www.cs.uni-dortmund.de/students/projectgroups/acit/lineclip.shtml
+*/
+template<typename Box, typename Point>
+class liang_barsky
+{
+private:
+    typedef ggl::segment<Point> segment_type;
+
+    inline bool check_edge(double const& p, double const& q, double& t1, double& t2) const
+    {
+        bool visible = true;
+
+        if(p < 0)
+        {
+            double const r = q / p;
+            if (r > t2)
+                visible = false;
+            else if (r > t1)
+                t1 = r;
+        }
+        else if(p > 0)
+        {
+            double const r = q / p;
+            if (r < t1)
+                visible = false;
+            else if (r < t2)
+                t2 = r;
+        }
+        else
+        {
+            if (q < 0)
+                visible = false;
+        }
+
+        return visible;
+    }
+
+public:
+
+    inline bool clip_segment(Box const& b, segment_type& s, bool& sp1_clipped, bool& sp2_clipped) const
+    {
+        typedef typename select_coordinate_type<Box, Point>::type coordinate_type;
+
+        double t1 = 0;
+        double t2 = 1;
+
+        coordinate_type const dx = get<1, 0>(s) - get<0, 0>(s);
+        coordinate_type const dy = get<1, 1>(s) - get<0, 1>(s);
+
+        coordinate_type const p1 = -dx;
+        coordinate_type const p2 = dx;
+        coordinate_type const p3 = -dy;
+        coordinate_type const p4 = dy;
+
+        coordinate_type const q1 = get<0, 0>(s) - get<min_corner, 0>(b);
+        coordinate_type const q2 = get<max_corner, 0>(b) - get<0, 0>(s);
+        coordinate_type const q3 = get<0, 1>(s) - get<min_corner, 1>(b);
+        coordinate_type const q4 = get<max_corner, 1>(b) - get<0, 1>(s);
+
+        if (check_edge(p1, q1, t1, t2)      // left
+            && check_edge(p2, q2, t1, t2)   // right
+            && check_edge(p3, q3, t1, t2)   // bottom
+            && check_edge(p4, q4, t1, t2))   // top
+        {
+            sp1_clipped = t1 > 0;
+            sp2_clipped = t2 < 1;
+
+            if (sp2_clipped)
+            {
+                set<1, 0>(s, get<0, 0>(s) + t2 * dx);
+                set<1, 1>(s, get<0, 1>(s) + t2 * dy);
+            }
+
+            if(sp1_clipped)
+            {
+                set<0, 0>(s, get<0, 0>(s) + t1 * dx);
+                set<0, 1>(s, get<0, 1>(s) + t1 * dy);
+            }
+
+            return true;
+        }
+
+        return false;
+    }
+
+    template<typename Linestring, typename OutputIterator>
+    inline void apply(Linestring& line_out, OutputIterator out) const
+    {
+        if (!boost::empty(line_out))
+        {
+            *out = line_out;
+            ++out;
+            ggl::clear(line_out);
+        }
+    }
+};
+
+
+}} // namespace strategy::intersection
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace intersection {
+
+/*!
+    \brief Clips a linestring with a box
+    \details A linestring is intersected (clipped) by the specified box
+    and the resulting linestring, or pieces of linestrings, are sent to the specified output operator.
+    \tparam OutputLinestring type of the output linestrings
+    \tparam OutputIterator an output iterator which outputs linestrings
+    \tparam Linestring linestring-type, for example a vector of points, matching the output-iterator type,
+         the points should also match the input-iterator type
+    \tparam Box box type
+    \tparam Strategy strategy, a clipping strategy which should implement the methods "clip_segment" and "apply"
+*/
+template
+<
+    typename OutputLinestring,
+    typename OutputIterator,
+    typename Linestring,
+    typename Box,
+    typename Strategy
+>
+OutputIterator clip_linestring_with_box(Box const& b, Linestring const& linestring,
+            OutputIterator out, Strategy const& strategy)
+{
+    if (boost::begin(linestring) == boost::end(linestring))
+    {
+        return out;
+    }
+
+    typedef typename point_type<OutputLinestring>::type point_type;
+
+    OutputLinestring line_out;
+
+    typedef typename boost::range_const_iterator<Linestring>::type iterator_type;
+    iterator_type vertex = boost::begin(linestring);
+    for(iterator_type previous = vertex++;
+            vertex != boost::end(linestring);
+            previous = vertex++)
+    {
+        point_type p1, p2;
+        copy_coordinates(*previous, p1);
+        copy_coordinates(*vertex, p2);
+
+        // Clip the segment. Five situations:
+        // 1. Segment is invisible, finish line if any (shouldn't occur)
+        // 2. Segment is completely visible. Add (p1)-p2 to line
+        // 3. Point 1 is invisible (clipped), point 2 is visible. Start new line from p1-p2...
+        // 4. Point 1 is visible, point 2 is invisible (clipped). End the line with ...p2
+        // 5. Point 1 and point 2 are both invisible (clipped). Start/finish an independant line p1-p2
+        //
+        // This results in:
+        // a. if p1 is clipped, start new line
+        // b. if segment is partly or completely visible, add the segment
+        // c. if p2 is clipped, end the line
+
+        bool c1 = false;
+        bool c2 = false;
+        segment<point_type> s(p1, p2);
+
+        if (!strategy.clip_segment(b, s, c1, c2))
+        {
+            strategy.apply(line_out, out);
+        }
+        else
+        {
+            // a. If necessary, finish the line and add a start a new one
+            if (c1)
+            {
+                strategy.apply(line_out, out);
+            }
+
+            // b. Add p1 only if it is the first point, then add p2
+            if (boost::empty(line_out))
+            {
+                ggl::append(line_out, p1);
+            }
+            ggl::append(line_out, p2);
+
+            // c. If c2 is clipped, finish the line
+            if (c2)
+            {
+                strategy.apply(line_out, out);
+            }
+        }
+
+    }
+
+    // Add last part
+    strategy.apply(line_out, out);
+    return out;
+}
+
+}} // namespace detail::intersection
+#endif // DOXYGEN_NO_DETAIL
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_OVERLAY_CLIP_LINESTRING_HPP
Added: sandbox/ggl/formal_review/boost/ggl/algorithms/overlay/copy_segments.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/algorithms/overlay/copy_segments.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,216 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_OVERLAY_COPY_SEGMENTS_HPP
+#define GGL_ALGORITHMS_OVERLAY_COPY_SEGMENTS_HPP
+
+
+#include <ggl/core/ring_type.hpp>
+#include <ggl/core/exterior_ring.hpp>
+#include <ggl/core/interior_rings.hpp>
+
+#include <ggl/geometries/concepts/check.hpp>
+
+#include <ggl/algorithms/overlay/intersection_point.hpp>
+
+#include <ggl/iterators/ever_circling_iterator.hpp>
+
+#include <ggl/iterators/range_type.hpp>
+
+
+namespace ggl
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace copy_segments {
+
+
+template <typename Ring, typename SegmentIdentifier, typename RangeOut>
+struct copy_segments_ring
+{
+    static inline void apply(Ring const& ring,
+            SegmentIdentifier const& seg_id, int to_index,
+            RangeOut& current_output)
+    {
+        typedef typename boost::range_const_iterator<Ring>::type iterator;
+
+        typedef ggl::ever_circling_iterator<iterator> ec_iterator;
+
+        // The problem: sometimes we want to from "3" to "2" -> end = "3" -> end == begin
+        // This is not convenient with iterators.
+
+        // So we use the ever-circling iterator and determine when to step out
+
+        int from_index = seg_id.segment_index + 1;
+
+        // Sanity check
+        BOOST_ASSERT(from_index < boost::size(ring));
+
+        ec_iterator it(boost::begin(ring), boost::end(ring),
+                    boost::begin(ring) + from_index);
+
+        // [2..4] -> 4 - 2 + 1 = 3 -> {2,3,4} -> OK
+        // [4..2],size=6 -> 6 - 4 + 2 + 1 = 5 -> {4,5,0,1,2} -> OK
+        // [1..1], travel the whole ring round
+        int count = from_index <= to_index
+            ? to_index - from_index + 1
+            : boost::size(ring) - from_index + to_index + 1;
+
+        for (int i = 0; i < count; ++i, ++it)
+        {
+            // TODO: use 'copy coordinates' to handle different point types
+#ifdef GGL_DEBUG_INTERSECTION
+            std::cout << "  add: ("
+                << ggl::get<0>(*it) << ", " << ggl::get<1>(*it) << ")"
+                << std::endl;
+#endif
+            current_output.push_back(*it);
+        }
+    }
+};
+
+
+template <typename Polygon, typename SegmentIdentifier, typename RangeOut>
+struct copy_segments_polygon
+{
+    static inline void apply(Polygon const& polygon,
+            SegmentIdentifier const& seg_id, int to_index,
+            RangeOut& current_output)
+    {
+        // Call ring-version with the right ring
+        copy_segments_ring
+            <
+                typename ggl::ring_type<Polygon>::type,
+                SegmentIdentifier,
+                RangeOut
+            >::apply
+                (
+                    seg_id.ring_index < 0
+                    ? ggl::exterior_ring(polygon)
+                    : ggl::interior_rings(polygon)[seg_id.ring_index],
+                    seg_id, to_index,
+                    current_output
+                );
+    }
+};
+
+
+template <typename Box, typename SegmentIdentifier, typename RangeOut>
+struct copy_segments_box
+{
+    static inline void apply(Box const& box,
+            SegmentIdentifier const& seg_id, int to_index,
+            RangeOut& current_output)
+    {
+        // Convert again...
+        // TODO: avoid that...
+
+        typedef typename point_type<Box>::type point_type;
+
+        point_type ll, lr, ul, ur;
+        assign_box_corners(box, ll, lr, ul, ur);
+
+        std::vector<point_type> points;
+        points.push_back(ll);
+        points.push_back(ul);
+        points.push_back(ur);
+        points.push_back(lr);
+        points.push_back(ll);
+
+        copy_segments_ring
+            <
+                std::vector<point_type>,
+                SegmentIdentifier,
+                RangeOut
+            >
+            ::apply(points, seg_id, to_index, current_output);
+    }
+};
+
+
+
+
+}} // namespace detail::copy_segments
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch {
+
+
+template
+<
+    typename Tag,
+    typename GeometryIn,
+    typename SegmentIdentifier,
+    typename RangeOut
+>
+struct copy_segments
+{
+};
+
+
+template <typename Ring, typename SegmentIdentifier, typename RangeOut>
+struct copy_segments<ring_tag, Ring, SegmentIdentifier, RangeOut>
+    : detail::copy_segments::copy_segments_ring
+        <
+            Ring, SegmentIdentifier, RangeOut
+        >
+{};
+
+template <typename Polygon, typename SegmentIdentifier, typename RangeOut>
+struct copy_segments<polygon_tag, Polygon, SegmentIdentifier, RangeOut>
+    : detail::copy_segments::copy_segments_polygon
+        <
+            Polygon, SegmentIdentifier, RangeOut
+        >
+{};
+
+
+template <typename Box, typename SegmentIdentifier, typename RangeOut>
+struct copy_segments<box_tag, Box, SegmentIdentifier, RangeOut>
+    : detail::copy_segments::copy_segments_box
+        <
+            Box, SegmentIdentifier, RangeOut
+        >
+{};
+
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+
+
+
+/*!
+    \brief Traverses through intersection points / geometries
+    \ingroup overlay
+ */
+template<typename Geometry, typename SegmentIdentifier, typename RangeOut>
+inline void copy_segments(Geometry const& geometry,
+            SegmentIdentifier const& seg_id, int to_index,
+            RangeOut& range_out)
+{
+    concept::check<const Geometry>();
+
+    dispatch::copy_segments
+        <
+            typename tag<Geometry>::type,
+            Geometry,
+            SegmentIdentifier,
+            RangeOut
+        >::apply(geometry, seg_id, to_index, range_out);
+}
+
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_OVERLAY_COPY_SEGMENTS_HPP
Added: sandbox/ggl/formal_review/boost/ggl/algorithms/overlay/enrich_intersection_points.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/algorithms/overlay/enrich_intersection_points.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,501 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_OVERLAY_ENRICH_INTERSECTION_POINTS_HPP
+#define GGL_ALGORITHMS_OVERLAY_ENRICH_INTERSECTION_POINTS_HPP
+
+#include <cstddef>
+#include <algorithm>
+#include <map>
+#include <vector>
+#ifdef GGL_DEBUG_INTERSECTION
+#include <iostream>
+#endif
+
+#include <boost/assert.hpp>
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace intersection {
+
+#ifdef GGL_DEBUG_INTERSECTION
+
+template <typename M>
+inline void report_map(M const& map)
+{
+    std::cout << "Map [source,segment(,ring,multi)] -> [count]:" << std::endl;
+    for (typename M::const_iterator it = map.begin(); it != map.end(); it++)
+    {
+        std::cout << "(" << it->first << ")"
+            << " -> " << "(" << it->second << ")" << std::endl;
+    }
+}
+
+
+template <typename V>
+inline void report_indexed(V const& index)
+{
+    typedef typename boost::range_const_iterator<V>::type iterator_type;
+
+    for (iterator_type it = boost::begin(index); it != boost::end(index); ++it)
+    {
+        std::cout << it->index << ": " << it->subject;
+    }
+}
+
+#endif // GGL_DEBUG_INTERSECTION
+
+
+template <typename T>
+struct indexed_source_segment
+{
+    std::size_t index;
+    T subject;
+
+    inline indexed_source_segment() {}
+
+    inline indexed_source_segment(std::size_t i, T const& s, segment_identifier const& seg_id)
+        : index(i)
+    {
+        s.clone_except_info(subject);
+
+        typedef typename T::traversal_vector vector_type;
+        for (typename boost::range_const_iterator<vector_type>::type it = s.info.begin();
+             it != s.info.end(); ++it)
+        {
+            // Copy info-record if belonging to source and to segment
+            if (it->seg_id == seg_id)
+            {
+                subject.info.push_back(*it);
+            }
+        }
+    }
+};
+
+
+template <typename T>
+struct indexed_source
+{
+    T subject;
+    std::size_t index;
+
+    inline indexed_source() {}
+
+    inline indexed_source(std::size_t i, T const& s,
+            int source_index, int multi_index, int ring_index)
+        : index(i)
+    {
+        s.clone_except_info(subject);
+
+        typedef typename T::traversal_vector vector_type;
+        for (typename boost::range_const_iterator<vector_type>::type it = s.info.begin();
+             it != s.info.end(); ++it)
+        {
+            // Copy info-record if belonging to source
+            if (it->seg_id.source_index == source_index
+                && it->seg_id.multi_index == multi_index
+                && it->seg_id.ring_index == ring_index)
+            {
+                subject.info.push_back(*it);
+            }
+        }
+    }
+};
+
+
+template <typename Indexed>
+struct sort_on_distance
+{
+    inline bool operator()(Indexed const& left, Indexed const& right) const
+    {
+        // Sanity check, there should be info-records because only those are copied
+        BOOST_ASSERT (left.subject.info.size() > 0 && right.subject.info.size() > 0);
+
+        return left.subject.info.front().distance < right.subject.info.front().distance;
+    }
+};
+
+// Sorts on segment + ring_index + multi_index
+template <typename Indexed>
+struct sort_on_segment_identifier
+{
+    inline bool operator()(Indexed const& left, Indexed const& right) const
+    {
+        // Sanity check
+        BOOST_ASSERT (left.subject.info.size() > 0 && right.subject.info.size() > 0);
+
+        segment_identifier const& sl = left.subject.info.front().seg_id;
+        segment_identifier const& sr = right.subject.info.front().seg_id;
+
+        return sl == sr
+            ? left.subject.info.front().distance < right.subject.info.front().distance
+            : sl < sr;
+    }
+};
+
+
+template <typename Info>
+struct on_source_segment_dir
+{
+    inline bool operator()(Info const& left, Info const& right) const
+    {
+        int ldir = left.direction;
+        int rdir = right.direction;
+        if (ldir == -1) ldir = 2;
+        if (rdir == -1) rdir = 2;
+
+
+        return left.seg_id.source_index == right.seg_id.source_index
+            ? (left.seg_id.segment_index == right.seg_id.segment_index
+                ? ldir < rdir
+                : left.seg_id.segment_index < right.seg_id.segment_index
+               )
+
+            : left.seg_id.source_index < right.seg_id.source_index;
+    }
+};
+
+
+
+
+
+// Assigns IP[index] . info[source/multi/ring/segment] . next_ip_index
+template <typename V>
+static inline void assign_next_ip_index(V& intersection_points, int index,
+            segment_identifier const& seg_id,
+            int next_ip_index)
+{
+    typedef typename boost::range_value<V>::type ip_type;
+    typedef typename ip_type::traversal_vector vector_type;
+    typedef typename boost::range_iterator<vector_type>::type iterator_type;
+
+    ip_type& ip = intersection_points[index];
+
+    for (iterator_type it = boost::begin(ip.info);
+            it != boost::end(ip.info);
+            ++it)
+    {
+        if (it->seg_id == seg_id)
+        {
+            it->next_ip_index = next_ip_index;
+            // Note: there can be MORE than one here. So do NOT return
+        }
+    }
+}
+
+
+// Assigns IP[index] . info[source_index] . travels_to_[vertex,ip]_index
+template <typename V>
+static inline void assign_last_vertex(V& intersection_points, int index,
+            int source_index,
+            int travels_to_vertex_index, int travels_to_ip_index)
+{
+    typedef typename boost::range_value<V>::type ip_type;
+    typedef typename ip_type::traversal_vector vector_type;
+    typedef typename boost::range_iterator<vector_type>::type iterator_type;
+
+    ip_type& ip = intersection_points[index];
+
+    for (iterator_type it = boost::begin(ip.info); it != boost::end(ip.info); ++it)
+    {
+        if (it->seg_id.source_index == source_index)
+        {
+            it->travels_to_vertex_index = travels_to_vertex_index;
+            it->travels_to_ip_index = travels_to_ip_index;
+            // do not return here, there can be more than one
+        }
+    }
+}
+
+
+// Creates selection of IP-s of only this unique source/segment,
+// then sorts on distance,
+// then assigns for each IP which is the next IP on this segment.
+// This is only applicable (but essential) for segments having
+// more than one IP on it. It is not the usual situation, so not
+// computational intensive.
+template <typename V>
+static inline bool assign_next_points(V& intersection_points,
+            segment_identifier const& seg_id)
+{
+    typedef typename boost::range_value<V>::type ip_type;
+    typedef typename boost::range_const_iterator<V>::type iterator_type;
+    typedef indexed_source_segment<ip_type> indexed_type;
+    typedef typename ip_type::traversal_vector vector_type;
+    typedef typename boost::range_const_iterator<vector_type>::type tvit_type;
+
+    // Create a copy of all IP's on this segment from this source
+
+    std::vector<indexed_type> copy;
+    copy.reserve(intersection_points.size());
+    std::size_t index = 0;
+    for (iterator_type it = boost::begin(intersection_points);
+         it != boost::end(intersection_points);
+         ++it, ++index)
+    {
+        bool to_be_copied = false;
+        for (tvit_type tvit = boost::begin(it->info);
+             !to_be_copied && tvit != boost::end(it->info);
+             ++tvit)
+        {
+            if (tvit->seg_id == seg_id)
+            {
+                to_be_copied = true;
+            }
+        }
+
+        if (to_be_copied)
+        {
+            // Copy this row, plus ONLY the related information
+            copy.push_back(indexed_type(index, *it, seg_id));
+        }
+    }
+
+    // Normally there are more elements in "copy".
+    // But in case of merges there could be only one.
+    if (boost::size(copy) <= 1)
+    {
+        return false;
+    }
+
+    std::sort(copy.begin(), copy.end(), sort_on_distance<indexed_type>());
+
+
+    // Now that it is sorted, do the main purpose: assign the next points
+    typedef typename boost::range_iterator
+        <
+            std::vector<indexed_type>
+        >::type indexed_iterator_type;
+
+    indexed_iterator_type it = boost::begin(copy);
+    for (indexed_iterator_type prev = it++; it != boost::end(copy); prev = it++)
+    {
+        for (
+#ifdef GGL_DEBUG_INTERSECTION
+        typename boost::range_iterator<vector_type>::type
+#else
+        tvit_type
+#endif
+            tvit = boost::begin(it->subject.info);
+             tvit != boost::end(it->subject.info);
+             ++tvit)
+        {
+            if (tvit->seg_id == seg_id)
+            {
+                assign_next_ip_index(intersection_points, prev->index, seg_id, it->index);
+
+#ifdef GGL_DEBUG_INTERSECTION
+                tvit->next_ip_index = it->index;
+#endif
+
+            }
+        }
+    }
+
+#ifdef GGL_DEBUG_INTERSECTION
+    std::cout << "Enrichment - sorted (on distance, " << seg_id << "): " << std::endl;
+    report_indexed(copy);
+#endif
+
+    return true;
+}
+
+
+// If a segment has more than one IP, we determine what is the next IP
+// on that segment
+template <typename M, typename V>
+static inline bool assign_next_points(M& map, V& intersection_points)
+{
+    bool assigned = false;
+    for (typename M::iterator mit = map.begin(); mit != map.end(); ++mit)
+    {
+        // IF there are more IP's on this segment
+        if (mit->second > 1)
+        {
+            if (assign_next_points(intersection_points, mit->first))
+            {
+                assigned = true;
+            }
+        }
+    }
+
+#ifdef GGL_DEBUG_INTERSECTION
+    std::cout << "Enrichment - assigned next points on same segment: " << std::endl;
+    report_ip(intersection_points);
+#endif
+
+    return assigned;
+}
+
+
+template <typename V>
+static inline bool assign_order(V& intersection_points,
+            int source_index, int multi_index, int ring_index)
+{
+    typedef typename boost::range_value<V>::type ip_type;
+    typedef typename boost::range_const_iterator<V>::type iterator_type;
+    typedef indexed_source<ip_type> indexed_type;
+    typedef typename ip_type::traversal_vector vector_type;
+    typedef typename boost::range_const_iterator<vector_type>::type tvit_type;
+
+    // Create a copy of all IP's from this source
+    std::vector<indexed_type> copy;
+    copy.reserve(intersection_points.size());
+    std::size_t index = 0;
+    for (iterator_type it = boost::begin(intersection_points);
+         it != boost::end(intersection_points);
+         ++it, ++index)
+    {
+        bool to_be_copied = false;
+        for (tvit_type tvit = boost::begin(it->info);
+             !to_be_copied && tvit != boost::end(it->info);
+             ++tvit)
+        {
+            if (tvit->seg_id.source_index == source_index
+                && tvit->seg_id.multi_index == multi_index
+                && tvit->seg_id.ring_index == ring_index)
+            {
+                to_be_copied = true;
+            }
+        }
+
+        if (to_be_copied)
+        {
+            // Copy this row, plus ONLY the related information
+            copy.push_back(indexed_type(index, *it, source_index, multi_index, ring_index));
+        }
+    }
+
+#ifdef GGL_DEBUG_INTERSECTION
+    std::cout << "Enrichment - ordered/copy (on segment "
+        << " src: " << source_index
+        << "): " << std::endl;
+    report_indexed(copy);
+#endif
+
+    std::sort(copy.begin(), copy.end(), sort_on_segment_identifier<indexed_type>());
+
+    typedef typename boost::range_const_iterator<std::vector<indexed_type> >::type iit_type;
+
+    // Now that it is sorted, do the main purpose:
+    // assign travel-to-vertex/ip index for each IP
+    // Because IP's are circular, PREV starts at the very last one,
+    // being assigned from the first one.
+    iit_type it = boost::begin(copy);
+    for (iit_type prev = it + (boost::size(copy) - 1);
+         it != boost::end(copy);
+         prev = it++)
+    {
+        for (tvit_type tvit = boost::begin(it->subject.info);
+             tvit != boost::end(it->subject.info);
+             ++tvit)
+        {
+            if (tvit->seg_id.source_index == source_index
+                && tvit->seg_id.multi_index == multi_index
+                && tvit->seg_id.ring_index == ring_index)
+            {
+                assign_last_vertex(intersection_points, prev->index, source_index,
+                    tvit->seg_id.segment_index, it->index);
+            }
+        }
+    }
+
+#ifdef GGL_DEBUG_INTERSECTION
+    std::cout << "Enrichment - ordered  on segment (src: "
+        << source_index << "): " << std::endl;
+    report_ip(intersection_points);
+#endif
+
+    return true;
+}
+
+template <typename M, typename V>
+static inline void assign_order(M const& map, V& intersection_points)
+{
+    typename M::const_iterator prev;
+    bool first = true;
+    for (typename M::const_iterator mit = map.begin(); mit != map.end(); ++mit)
+    {
+        if (first
+            || prev->first.source_index != mit->first.source_index
+            || prev->first.ring_index != mit->first.ring_index
+            || prev->first.multi_index != mit->first.multi_index)
+        {
+            assign_order(intersection_points, mit->first.source_index,
+                         mit->first.multi_index, mit->first.ring_index);
+            first = false;
+        }
+        prev = mit;
+    }
+
+#ifdef GGL_DEBUG_INTERSECTION
+    std::cout << "Enrichment - assigned order: " << std::endl;
+    report_ip(intersection_points);
+#endif
+
+}
+
+
+
+
+}} // namespace detail::intersection
+#endif //DOXYGEN_NO_DETAIL
+
+
+/*!
+    \brief All intersection points are enriched with successor information
+    \ingroup overlay
+    \tparam IntersectionPoints type of intersection container (e.g. vector of "intersection_point"'s)
+    \param intersection_points container containing intersectionpoints
+    \param trivial Boolean flag to indicate that it is trivial, only intersections,
+        no touch, collinearities, etc.
+ */
+template <typename IntersectionPoints>
+inline void enrich_intersection_points(IntersectionPoints& intersection_points, bool trivial)
+{
+
+    // Create a map of segment<source_index,segment_index,ring_index,multi_index>
+    // to <number of IP's on this segment>
+    // Purpose: count IP's per source/segment, sort them lateron
+    std::map<segment_identifier, int> map;
+
+    typedef typename boost::range_const_iterator<IntersectionPoints>::type iterator_type;
+    for (iterator_type it = boost::begin(intersection_points);
+         it != boost::end(intersection_points);
+         ++it)
+    {
+        typedef typename boost::range_value
+            <
+                IntersectionPoints
+            >::type::traversal_vector vector_type;
+        typedef typename boost::range_const_iterator<vector_type>::type tvit_type;
+        for (tvit_type tvit = boost::begin(it->info);
+            tvit != boost::end(it->info);
+            ++tvit)
+        {
+            map[tvit->seg_id]++;
+        }
+    }
+
+#ifdef GGL_DEBUG_INTERSECTION
+    detail::intersection::report_map(map);
+#endif
+
+    detail::intersection::assign_next_points(map, intersection_points);
+
+    detail::intersection::assign_order(map, intersection_points);
+}
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_OVERLAY_ENRICH_INTERSECTION_POINTS_HPP
Added: sandbox/ggl/formal_review/boost/ggl/algorithms/overlay/get_intersection_points.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/algorithms/overlay/get_intersection_points.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,792 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_OVERLAY_GET_INTERSECTION_POINTS_HPP
+#define GGL_ALGORITHMS_OVERLAY_GET_INTERSECTION_POINTS_HPP
+
+/*!
+\defgroup overlay overlay helper operations (getting intersection points, etc)
+*/
+
+
+#include <cstddef>
+
+#include <boost/mpl/if.hpp>
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+#include <boost/tuple/tuple.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/coordinate_dimension.hpp>
+#include <ggl/core/is_multi.hpp>
+#include <ggl/core/reverse_dispatch.hpp>
+
+#include <ggl/core/exterior_ring.hpp>
+#include <ggl/core/interior_rings.hpp>
+#include <ggl/core/ring_type.hpp>
+
+#include <ggl/geometries/concepts/check.hpp>
+
+#include <ggl/util/math.hpp>
+
+#include <ggl/geometries/box.hpp>
+
+#include <ggl/iterators/range_type.hpp>
+
+#include <ggl/strategies/cartesian/cart_intersect.hpp>
+#include <ggl/strategies/intersection_result.hpp>
+
+#include <ggl/policies/relate/intersection_points.hpp>
+#include <ggl/policies/relate/direction.hpp>
+#include <ggl/policies/relate/tupled.hpp>
+
+#include <ggl/algorithms/overlay/intersection_point.hpp>
+
+#include <ggl/algorithms/detail/disjoint.hpp>
+
+#include <ggl/algorithms/distance.hpp>
+#include <ggl/algorithms/sectionalize.hpp>
+#include <ggl/algorithms/get_section.hpp>
+#include <ggl/algorithms/within.hpp>
+
+
+
+namespace ggl
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace get_intersection_points {
+
+
+template <typename Segment1, typename Segment2, typename IntersectionPoints>
+struct relate
+{
+    static inline bool apply(Segment1 const& s1, Segment2 const& s2,
+                segment_identifier const& seg_id1,
+                segment_identifier const& seg_id2,
+                IntersectionPoints& out, bool& trivial)
+    {
+
+        typedef typename boost::range_value
+            <
+                IntersectionPoints
+            >::type intersection_point;
+        typedef segment_intersection_points<intersection_point> ip_type;
+
+        typedef boost::tuple
+            <
+                ip_type,
+                policies::relate::direction_type
+            > result_type;
+
+        result_type result = strategy::intersection::relate_cartesian_segments
+            <
+                policies::relate::segments_tupled
+                    <
+                        policies::relate::segments_intersection_points
+                            <
+                                Segment1,
+                                Segment2,
+                                ip_type
+                            > ,
+                        policies::relate::segments_direction
+                            <
+                                Segment1,
+                                Segment2
+                            >
+                    >
+            >::relate(s1, s2);
+
+        ip_type& is = result.get<0>();
+        policies::relate::direction_type & dir = result.get<1>();
+
+        for (int i = 0; i < is.count; i++)
+        {
+            typedef typename point_type<Segment1>::type point1_type;
+            typedef typename cs_tag<point1_type>::type tag;
+
+            typename intersection_point::traversal_type info;
+
+            info.how = dir.how;
+            info.opposite = dir.opposite;
+
+            // First info-record, containing info about segment 1
+            info.seg_id = seg_id1;
+            info.other_id = seg_id2;
+            info.other_point = dir.how_a == 1 ? s1.first : s1.second;
+
+            info.distance = ggl::distance(is.intersections[i], s1.first);
+
+            //info.distance = dir.ra; // NOTE: not possible for collinear intersections!
+            info.arrival = dir.how_a;
+            info.direction = dir.dir_a;
+            is.intersections[i].info.push_back(info);
+
+
+            // Second info-record, containing info about segment 2
+            info.seg_id = seg_id2;
+            info.other_id = seg_id1;
+            info.other_point = dir.how_b == 1 ? s2.first : s2.second;
+
+            info.distance = ggl::distance(is.intersections[i], s2.first);
+            //info.distance = dir.rb;
+
+            info.arrival = dir.how_b;
+            info.direction = dir.dir_b;
+            is.intersections[i].info.push_back(info);
+
+            if (dir.how != 'i')
+            {
+                trivial = false;
+                is.intersections[i].trivial = false;
+            }
+
+            // Robustness: due to IEEE floating point errors, also in double, it might be
+            // that the IP is at the same location as s1.first/s1.second, and still
+            // being classified as an 'i' (normal intersection). Then handle it as non-trivial,
+            // such that the IP's will be merged lateron.
+
+            double eps = 1.0e-10;
+            if (dir.how == 'i'
+                && (dir.ra < eps
+                    || dir.rb < eps
+                    || 1.0 - dir.ra < eps
+                    || 1.0 - dir.rb <  eps
+                    )
+                )
+            {
+                // Handle them as non-trivial. This will case a "merge" lateron,
+                // which could be done anyway (because of other intersections)
+                // So it is never harmful to do this with a larger epsilon.
+                // However, it has to be handled (more) carefully lateron, in
+                // 'merge' or 'adapt_turns'
+                trivial = false;
+                is.intersections[i].trivial = false;
+
+
+#ifdef GGL_DEBUG_INTERSECTION
+                std::cout << "INTERSECTION suspicious: " << std::setprecision(20)
+                    << " ra: " << dir.ra
+                    << " rb: " << dir.rb
+                    << std::endl
+                    << " dist1: " << ggl::distance(is.intersections[i], s1.first)
+                    << " dist2: " << ggl::distance(is.intersections[i], s1.second)
+                    << std::endl;
+#endif
+            }
+
+            out.push_back(is.intersections[i]);
+        }
+        return is.count > 0;
+    }
+};
+
+template
+<
+    typename Geometry1, typename Geometry2,
+    typename Section1, typename Section2,
+    typename IntersectionPoints
+>
+class get_ips_in_sections
+{
+public :
+    static inline void apply(
+            std::size_t source_id1, Geometry1 const& geometry1,
+                Section1 const& sec1,
+            std::size_t source_id2, Geometry2 const& geometry2,
+                Section2 const& sec2,
+            bool return_if_found,
+            IntersectionPoints& intersection_points,
+            bool& trivial)
+    {
+
+        typedef typename boost::range_const_iterator
+            <
+                typename ggl::range_type<Geometry1>::type
+            >::type range1_iterator;
+        typedef typename boost::range_const_iterator
+            <
+                typename ggl::range_type<Geometry2>::type
+            >::type range2_iterator;
+
+        int const dir1 = sec1.directions[0];
+        int const dir2 = sec2.directions[0];
+        int index1 = sec1.begin_index;
+        int ndi1 = sec1.non_duplicate_index;
+
+        bool const same_source =
+            source_id1 == source_id2
+                    && sec1.multi_index == sec2.multi_index
+                    && sec1.ring_index == sec2.ring_index;
+
+        // Note that it is NOT possible to have section-iterators here
+        // because of the logistics of "index" (the section-iterator automatically
+        // skips to the begin-point, we loose the index or have to recalculate it)
+        // So we mimic it here
+        range1_iterator it1, end1;
+        get_section(geometry1, sec1, it1, end1);
+
+        // Mimic 1: Skip to point such that section interects other box
+        range1_iterator prev1 = it1++;
+        for(; it1 != end1 && preceding<0>(dir1, *it1, sec2.bounding_box);
+            prev1 = it1++, index1++, ndi1++)
+        {
+        }
+        // Go back one step because we want to start completely preceding
+        it1 = prev1;
+
+        // Walk through section and stop if we exceed the other box
+        for (prev1 = it1++;
+            it1 != end1 && ! exceeding<0>(dir1, *prev1, sec2.bounding_box);
+            prev1 = it1++, index1++, ndi1++)
+        {
+            segment1_type s1(*prev1, *it1);
+
+            int index2 = sec2.begin_index;
+            int ndi2 = sec2.non_duplicate_index;
+
+            range2_iterator it2, end2;
+            get_section(geometry2, sec2, it2, end2);
+
+            range2_iterator prev2 = it2++;
+
+            // Mimic 2:
+            for(; it2 != end2 && preceding<0>(dir2, *it2, sec1.bounding_box);
+                prev2 = it2++, index2++, ndi2++)
+            {
+            }
+            it2 = prev2;
+
+            for (prev2 = it2++;
+                it2 != end2 && ! exceeding<0>(dir2, *prev2, sec1.bounding_box);
+                prev2 = it2++, index2++, ndi2++)
+            {
+                bool skip = same_source;
+                if (skip)
+                {
+                    // If sources are the same (possibly self-intersecting):
+                    // check if it is a neighbouring sement.
+                    // (including first-last segment
+                    //  and two segments with one or more degenerate/duplicate
+                    //  (zero-length) segments in between)
+
+                    // Also skip if index1 < index2 to avoid getting all
+                    // intersections twice (only do this on same source!)
+
+                    // About n-2:
+                    //   (square: range_count=5, indices 0,1,2,3
+                    //    -> 0-3 are adjacent)
+                    skip = index2 >= index1
+                        || ndi1 == ndi2 + 1
+                        || (index2 == 0 && index1 >= int(sec1.range_count) - 2)
+                        ;
+                }
+
+                if (! skip)
+                {
+                    if (relate<segment1_type, segment2_type, IntersectionPoints>
+                        ::apply(s1, segment2_type(*prev2, *it2),
+                            segment_identifier(source_id1,
+                                        sec1.multi_index, sec1.ring_index, index1),
+                            segment_identifier(source_id2,
+                                        sec2.multi_index, sec2.ring_index, index2),
+                            intersection_points, trivial)
+                        && return_if_found)
+                    {
+                        return;
+                    }
+                }
+            }
+        }
+    }
+
+
+private :
+    typedef typename ggl::point_type<Geometry1>::type point1_type;
+    typedef typename ggl::point_type<Geometry2>::type point2_type;
+    typedef typename ggl::segment<const point1_type> segment1_type;
+    typedef typename ggl::segment<const point2_type> segment2_type;
+
+
+    template <size_t Dim, typename Point, typename Box>
+    static inline bool preceding(int dir, Point const& point, Box const& box)
+    {
+        return (dir == 1  && get<Dim>(point) < get<min_corner, Dim>(box))
+            || (dir == -1 && get<Dim>(point) > get<max_corner, Dim>(box));
+    }
+
+    template <size_t Dim, typename Point, typename Box>
+    static inline bool exceeding(int dir, Point const& point, Box const& box)
+    {
+        return (dir == 1  && get<Dim>(point) > get<max_corner, Dim>(box))
+            || (dir == -1 && get<Dim>(point) < get<min_corner, Dim>(box));
+    }
+
+
+};
+
+
+template
+<
+    typename Ring, typename Box,
+    typename Section1, typename Section2,
+    typename IntersectionPoints
+>
+class get_ips_range_box
+{
+public :
+    static inline void apply(
+            std::size_t source_id1, Ring const& ring,
+            std::size_t source_id2, Box const& box,
+            Section1 const& sec1, Section2 const& sec2,
+            IntersectionPoints& intersection_points, bool& trivial)
+    {
+        get_ips_in_sections<Ring, Box, Section1, Section2, IntersectionPoints>
+            ::apply(
+                source_id1, ring, sec1,
+                source_id2, box, sec2,
+                false,
+                intersection_points, trivial);
+    }
+};
+
+
+
+
+template<typename Geometry1, typename Geometry2, typename IntersectionPoints>
+struct get_ips_generic
+{
+    static inline bool apply(
+            std::size_t source_id1, Geometry1 const& geometry1,
+            std::size_t source_id2, Geometry2 const& geometry2,
+            IntersectionPoints& intersection_points)
+    {
+        // Create monotonic sections in ONE direction
+        // - in most cases ONE direction is faster (e.g. ~1% faster for the NLP4 testset)
+        // - the sections now have a limit (default 10) so will not be too large
+        typedef typename ggl::sections
+            <
+                ggl::box < typename ggl::point_type<Geometry1>::type >, 1
+            > sections1_type;
+        typedef typename ggl::sections
+            <
+                ggl::box < typename ggl::point_type<Geometry2>::type >, 1
+            > sections2_type;
+
+        sections1_type sec1;
+        sections2_type sec2;
+
+        ggl::sectionalize(geometry1, sec1);
+        ggl::sectionalize(geometry2, sec2);
+
+        bool trivial = true;
+        for (typename boost::range_const_iterator<sections1_type>::type
+                    it1 = sec1.begin();
+            it1 != sec1.end();
+            ++it1)
+        {
+            for (typename boost::range_const_iterator<sections2_type>::type
+                        it2 = sec2.begin();
+                it2 != sec2.end();
+                ++it2)
+            {
+                if (! ggl::detail::disjoint::disjoint_box_box(
+                                it1->bounding_box, it2->bounding_box))
+                {
+                    get_ips_in_sections
+                    <
+                        Geometry1,
+                        Geometry2,
+                        typename boost::range_value<sections1_type>::type,
+                        typename boost::range_value<sections2_type>::type,
+                        IntersectionPoints
+                    >::apply(
+                            source_id1, geometry1, *it1,
+                            source_id2, geometry2, *it2,
+                            false,
+                            intersection_points, trivial);
+                }
+            }
+        }
+        return trivial;
+    }
+};
+
+
+
+template<typename Range, typename Box, typename IntersectionPoints>
+struct get_ips_cs
+{
+    static inline void apply(std::size_t source_id1, Range const& range,
+            int multi_index, int ring_index,
+            std::size_t source_id2, Box const& box,
+            IntersectionPoints& intersection_points,
+            bool& trivial)
+    {
+        if (boost::size(range) <= 1)
+        {
+            return;
+        }
+
+
+        typedef typename ggl::point_type<Box>::type box_point_type;
+        typedef typename ggl::point_type<Range>::type point_type;
+
+        typedef segment<const box_point_type> box_segment_type;
+        typedef segment<const point_type> segment_type;
+
+        point_type lower_left, upper_left, lower_right, upper_right;
+        assign_box_corners(box, lower_left, lower_right, upper_left, upper_right);
+
+        box_segment_type left(lower_left, upper_left);
+        box_segment_type top(upper_left, upper_right);
+        box_segment_type right(upper_right, lower_right);
+        box_segment_type bottom(lower_right, lower_left);
+
+
+        typedef typename boost::range_const_iterator<Range>::type iterator_type;
+        iterator_type it = boost::begin(range);
+
+        bool first = true;
+
+        char previous_side[2] = {0, 0};
+
+        int index = 0;
+
+        for (iterator_type prev = it++;
+            it != boost::end(range);
+            prev = it++, index++)
+        {
+            segment_type segment(*prev, *it);
+
+            if (first)
+            {
+                previous_side[0] = get_side<0>(box, *prev);
+                previous_side[1] = get_side<1>(box, *prev);
+            }
+
+            char current_side[2];
+            current_side[0] = get_side<0>(box, *it);
+            current_side[1] = get_side<1>(box, *it);
+
+            // There can NOT be intersections if
+            // 1) EITHER the two points are lying on one side of the box (! 0 && the same)
+            // 2) OR same in Y-direction
+            // 3) OR all points are inside the box (0)
+            /*if (! (
+                (current_side[0] != 0 && current_side[0] == previous_side[0])
+                || (current_side[1] != 0 && current_side[1] == previous_side[1])
+                || (current_side[0] == 0
+                        && current_side[1] == 0
+                        && previous_side[0] == 0
+                        && previous_side[1] == 0)
+                  )
+                )*/
+            if (true)
+            {
+                segment_identifier seg_id(source_id1,
+                            multi_index, ring_index, index);
+
+                typedef relate
+                    <
+                        segment_type, box_segment_type, IntersectionPoints
+                    > relater;
+
+                // Depending on code some relations can be left out
+                relater::apply(segment, left, seg_id,
+                        segment_identifier(source_id2, -1, -1, 0),
+                        intersection_points, trivial);
+                relater::apply(segment, top, seg_id,
+                        segment_identifier(source_id2, -1, -1, 1),
+                        intersection_points, trivial);
+                relater::apply(segment, right, seg_id,
+                        segment_identifier(source_id2, -1, -1, 2),
+                        intersection_points, trivial);
+                relater::apply(segment, bottom, seg_id,
+                        segment_identifier(source_id2, -1, -1, 3),
+                        intersection_points, trivial);
+
+            }
+        }
+    }
+
+private:
+    template<std::size_t Index, typename Point>
+    static inline int get_side(Box const& box, Point const& point)
+    {
+        // Inside -> 0
+        // Outside -> -1 (left/below) or 1 (right/above)
+        // On border -> -2 (left/lower) or 2 (right/upper)
+        // The only purpose of the value is to not be the same,
+        // and to denote if it is inside (0)
+
+        typename coordinate_type<Point>::type const& c = get<Index>(point);
+        typename coordinate_type<Box>::type const& left = get<min_corner, Index>(box);
+        typename coordinate_type<Box>::type const& right = get<max_corner, Index>(box);
+
+        if (ggl::math::equals(c, left)) return -2;
+        else if (ggl::math::equals(c, right)) return 2;
+        else if (c < left) return -1;
+        else if (c > right) return 1;
+        else return 0;
+    }
+
+
+};
+
+
+}} // namespace detail::get_intersection_points
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+    typename GeometryTag1, typename GeometryTag2,
+    bool IsMulti1, bool IsMulti2,
+    typename Geometry1, typename Geometry2,
+    typename IntersectionPoints
+
+>
+struct get_intersection_points
+{
+};
+
+
+template<typename Polygon, typename Box, typename IntersectionPoints>
+struct get_intersection_points
+    <
+        polygon_tag, box_tag, false, false,
+        Polygon, Box,
+        IntersectionPoints
+    >
+{
+
+    static inline bool apply(
+            std::size_t source_id1, Polygon const& polygon,
+            std::size_t source_id2, Box const& box,
+            IntersectionPoints& intersection_points)
+    {
+        typedef typename ggl::ring_type<Polygon>::type ring_type;
+
+        typedef typename boost::range_const_iterator
+            <
+                typename interior_type<Polygon>::type
+            >::type iterator_type;
+
+
+        typedef detail::get_intersection_points::get_ips_cs
+            <ring_type, Box, IntersectionPoints> intersector_type;
+
+        bool trivial = true;
+        intersector_type::apply(
+                source_id1, ggl::exterior_ring(polygon), -1, -1,
+                source_id2, box,
+                intersection_points, trivial);
+
+        int i = 0;
+        for (iterator_type it = boost::begin(interior_rings(polygon));
+             it != boost::end(interior_rings(polygon));
+             ++it, ++i)
+        {
+            intersector_type::apply(
+                    source_id1, *it, -1, i,
+                    source_id2, box, intersection_points, trivial);
+        }
+
+        return trivial;
+    }
+};
+
+
+template<typename Ring, typename Box, typename IntersectionPoints>
+struct get_intersection_points
+    <
+        ring_tag, box_tag, false, false,
+        Ring, Box,
+        IntersectionPoints
+    >
+{
+    static inline bool apply(
+            std::size_t source_id1, Ring const& ring,
+            std::size_t source_id2, Box const& box,
+            IntersectionPoints& intersection_points)
+    {
+        typedef typename boost::range_const_iterator
+            <
+                Ring
+            >::type iterator_type;
+
+        typedef detail::get_intersection_points::get_ips_cs
+            <Ring, Box, IntersectionPoints> intersector_type;
+
+        bool trivial = true;
+        intersector_type::apply(
+                source_id1, ring, -1, -1,
+                source_id2, box,
+                intersection_points, trivial);
+
+        return trivial;
+    }
+};
+
+
+template<typename Ring1, typename Ring2, typename IntersectionPoints>
+struct get_intersection_points
+    <
+        ring_tag, ring_tag, false, false,
+        Ring1, Ring2,
+        IntersectionPoints
+    >
+    : detail::get_intersection_points::get_ips_generic
+        <
+            Ring1,
+            Ring2,
+            IntersectionPoints
+        >
+{};
+
+
+template<typename Polygon1, typename Polygon2, typename IntersectionPoints>
+struct get_intersection_points
+    <
+        polygon_tag, polygon_tag, false, false,
+        Polygon1, Polygon2,
+        IntersectionPoints
+    >
+    : detail::get_intersection_points::get_ips_generic
+        <
+            Polygon1,
+            Polygon2,
+            IntersectionPoints
+        >
+{};
+
+template<typename Polygon, typename Ring, typename IntersectionPoints>
+struct get_intersection_points
+    <
+        polygon_tag, ring_tag, false, false,
+        Polygon, Ring,
+        IntersectionPoints
+    >
+    : detail::get_intersection_points::get_ips_generic
+        <
+            Polygon,
+            Ring,
+            IntersectionPoints
+        >
+{};
+
+template
+<
+    typename LineString1,
+    typename LineString2,
+    typename IntersectionPoints
+>
+struct get_intersection_points
+    <
+        linestring_tag, linestring_tag, false, false,
+        LineString1, LineString2,
+        IntersectionPoints
+    >
+    : detail::get_intersection_points::get_ips_generic
+        <
+            LineString1,
+            LineString2,
+            IntersectionPoints
+        >
+{};
+
+template
+<
+    typename GeometryTag1, typename GeometryTag2,
+    bool IsMulti1, bool IsMulti2,
+    typename Geometry1, typename Geometry2,
+    typename IntersectionPoints
+>
+struct get_intersection_points_reversed
+{
+    static inline bool apply(
+            std::size_t source_id1, Geometry1 const& g1,
+            std::size_t source_id2, Geometry2 const& g2,
+            IntersectionPoints& intersection_points)
+    {
+        return get_intersection_points
+            <
+                GeometryTag2, GeometryTag1,
+                IsMulti2, IsMulti1,
+                Geometry2, Geometry1,
+                IntersectionPoints
+            >::apply(source_id2, g2, source_id1, g1, intersection_points);
+    }
+};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+
+/*!
+    \brief Calculate intersection points of two geometries
+    \ingroup overlay
+    \tparam Geometry1 first geometry type
+    \tparam Geometry2 second geometry type
+    \tparam IntersectionPoints type of intersection container (e.g. vector of "intersection_point"'s)
+    \param geometry1 first geometry
+    \param geometry2 second geometry
+    \param intersection_points container which will contain intersection points
+    \return TRUE if it is trivial, else FALSE
+ */
+template <typename Geometry1, typename Geometry2, typename IntersectionPoints>
+inline bool get_intersection_points(Geometry1 const& geometry1,
+            Geometry2 const& geometry2, IntersectionPoints& intersection_points)
+{
+    concept::check_concepts_and_equal_dimensions<const Geometry1, const Geometry2>();
+
+    typedef typename boost::remove_const<Geometry1>::type ncg1_type;
+    typedef typename boost::remove_const<Geometry2>::type ncg2_type;
+
+    return boost::mpl::if_c
+        <
+            reverse_dispatch<Geometry1, Geometry2>::type::value,
+            dispatch::get_intersection_points_reversed
+            <
+                typename tag<ncg1_type>::type,
+                typename tag<ncg2_type>::type,
+                is_multi<ncg1_type>::type::value,
+                is_multi<ncg2_type>::type::value,
+                ncg1_type,
+                ncg2_type,
+                IntersectionPoints
+            >,
+            dispatch::get_intersection_points
+            <
+                typename tag<ncg1_type>::type,
+                typename tag<ncg2_type>::type,
+                is_multi<ncg1_type>::type::value,
+                is_multi<ncg2_type>::type::value,
+                ncg1_type,
+                ncg2_type,
+               IntersectionPoints
+            >
+        >::type::apply(
+            0, geometry1,
+            1, geometry2,
+            intersection_points);
+}
+
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_OVERLAY_GET_INTERSECTION_POINTS_HPP
Added: sandbox/ggl/formal_review/boost/ggl/algorithms/overlay/intersection_point.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/algorithms/overlay/intersection_point.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,259 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_INTERSECTION_POINT_HPP
+#define GGL_ALGORITHMS_INTERSECTION_POINT_HPP
+
+#include <vector>
+
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/coordinate_dimension.hpp>
+
+#include <ggl/strategies/distance.hpp>
+#include <ggl/strategies/distance_result.hpp>
+
+#include <ggl/algorithms/overlay/segment_identifier.hpp>
+
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace intersection {
+
+
+template<typename P>
+struct intersection_info
+{
+    typedef P point_type;
+    typedef typename distance_result<P, P>::type distance_type;
+
+    inline intersection_info()
+        : travels_to_vertex_index(-1)
+        , travels_to_ip_index(-1)
+        , next_ip_index(-1)
+        , distance(ggl::make_distance_result<distance_type>(0))
+        , direction(0)
+        , how('?')
+        , arrival(0)
+        , opposite(false)
+        , visit_code(0)
+        , flagged(false)
+    {}
+
+    // Point to which the segment from IP is directing (TO-point)
+    // If they intersect on their "arrival" points, it is the FROM-point.
+    P other_point;
+
+    // Identifier of this segment (source,segment,ring,multi)
+    segment_identifier seg_id;
+
+    // Identify the segment where it was intersected with to form this IP
+    segment_identifier other_id;
+
+
+    // vertex to which is free travel after this IP,
+    // so from "segment_index+1" to "travels_to_vertex_index", without IP-s,
+    // can be -1
+    int travels_to_vertex_index;
+
+    // same but now IP index, so "next IP index" but not on THIS segment
+    int travels_to_ip_index;
+
+    // index of next IP on this segment, -1 if there is no one
+    int next_ip_index;
+
+    distance_type distance; // distance-measurement from segment.first to IP
+
+    // 1: left, -1: right, 0: collinear
+    int direction;
+
+    // Information about how intersection is done
+    char how;
+
+    // 1: arrived at IP, -1: departs from IP, 0: crosses IP
+    int arrival;
+
+    bool opposite;
+
+    int visit_code;
+
+    bool flagged; // flagged for deletion
+
+#ifdef GGL_DEBUG_INTERSECTION
+        static inline std::string dir(int d)
+        {
+            return d == 0 ? "-" : (d == 1 ? "L" : d == -1 ? "R" : "#");
+        }
+        static inline std::string how_str(int h)
+        {
+            return h == 0 ? "-" : (h == 1 ? "A" : "D");
+        }
+
+        friend std::ostream& operator<<(std::ostream &os, intersection_info<P> const& info)
+        {
+            os  << "\t"
+                << " src " << info.seg_id.source_index
+                << " seg " << info.seg_id.segment_index
+                << " (// " << info.other_id.source_index
+                    << "." << info.other_id.segment_index << ")"
+                << " how " << info.how
+                    << "[" << how_str(info.arrival)
+                    << " " << dir(info.direction)
+                    << (info.opposite ? " o" : "")
+                    << "]"
+                << " nxt seg " << info.travels_to_vertex_index
+                << " , ip " << info.travels_to_ip_index
+                << " , or " << info.next_ip_index
+                << " dst " 
+                    //<< std::setprecision(12) 
+                    << double(info.distance);
+            if (info.visit_code != 0)
+            {
+                os << " VIS: " << int(info.visit_code);
+            }
+            if (info.flagged)
+            {
+                os << " FLAGGED";
+            }
+            return os;
+        }
+#endif
+};
+
+
+template<typename P>
+struct intersection_point
+{
+    public :
+        inline intersection_point()
+            : visit_code(0) // VISIT_NONE
+            , trivial(true)
+            , shared(false)
+            , flagged(false)
+        {
+        }
+
+
+#ifdef GGL_DEBUG_INTERSECTION
+        friend std::ostream& operator<<(std::ostream &os, intersection_point<P> const& p)
+        {
+            os << "IP (" << ggl::get<0>(p.point) << "," << ggl::get<1>(p.point) << ")"
+                << " visited: " << int(p.visit_code)
+                << (p.shared ? " SHARED" : "")
+                << (p.flagged ? " FLAGGED" : "")
+                << std::endl;
+
+            for (unsigned int i = 0; i < p.info.size(); i++)
+            {
+                os << p.info[i] << std::endl;
+            }
+            return os;
+        }
+#endif
+        typedef intersection_info<P> traversal_type;
+        typedef std::vector<traversal_type> traversal_vector;
+
+        P point;
+
+        int visit_code;
+        bool trivial; // FALSE if there is an collinearity, touch or so.
+        bool shared; // shared with more IP's
+        bool flagged; // flagged for deletion afterwards
+
+        // info about the two intersecting segments
+        // usually two, but often more if IP's are merged
+        traversal_vector info;
+
+        inline void clone_except_info(intersection_point& other) const
+        {
+            other.point = point;
+            other.visit_code = visit_code;
+            other.trivial = trivial;
+            other.shared = shared;
+            other.flagged = flagged;
+        }
+};
+
+
+
+
+}} // namespace detail::intersection
+#endif //DOXYGEN_NO_DETAIL
+
+
+// Register the intersection point as being a point fulfilling the ggl Point Concept
+namespace traits
+{
+
+    template <typename P>
+    struct coordinate_type<ggl::detail::intersection::intersection_point<P> >
+    {
+        typedef typename ggl::coordinate_type<P>::type type;
+    };
+
+    template <typename P>
+    struct coordinate_system<ggl::detail::intersection::intersection_point<P> >
+    {
+        typedef typename ggl::coordinate_system<P>::type type;
+    };
+
+    template <typename P>
+    struct dimension<ggl::detail::intersection::intersection_point<P> >
+        : ggl::dimension<P>
+    {};
+
+    template <typename P>
+    struct tag<ggl::detail::intersection::intersection_point<P> >
+    {
+        typedef point_tag type;
+    };
+
+    template <typename P, std::size_t Dimension>
+    struct access<ggl::detail::intersection::intersection_point<P>, Dimension>
+    {
+        static inline typename coordinate_type<P>::type get(
+                ggl::detail::intersection::intersection_point<P> const& p)
+        {
+            return ggl::get<Dimension>(p.point);
+        }
+
+        static inline void set(ggl::detail::intersection::intersection_point<P>& p,
+                typename coordinate_type<P>::type const& value)
+        {
+            ggl::set<Dimension>(p.point, value);
+        }
+    };
+
+}
+
+
+#ifdef GGL_DEBUG_INTERSECTION
+
+template <typename V>
+inline void report_ip(V const& intersection_points)
+{
+    typedef typename V::const_iterator iterator_type;
+
+    for (iterator_type it = intersection_points.begin();
+         it != intersection_points.end();
+         ++it)
+    {
+        if (! it->flagged)
+        {
+            std::cout << *it;
+        }
+    }
+}
+#endif // GGL_DEBUG_INTERSECTION
+
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_INTERSECTION_POINT_HPP
Added: sandbox/ggl/formal_review/boost/ggl/algorithms/overlay/merge_intersection_points.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/algorithms/overlay/merge_intersection_points.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,265 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_OVERLAY_MERGE_INTERSECTION_POINTS_HPP
+#define GGL_ALGORITHMS_OVERLAY_MERGE_INTERSECTION_POINTS_HPP
+
+#include <algorithm>
+
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+
+#include <ggl/core/coordinate_type.hpp>
+
+#include <ggl/algorithms/detail/disjoint.hpp>
+#include <ggl/algorithms/overlay/intersection_point.hpp>
+
+
+namespace ggl
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace intersection {
+
+template <typename PointType>
+struct on_increasing_dimension
+{
+    typedef typename ggl::coordinate_type<PointType>::type coordinate_type;
+
+    inline bool operator()(PointType const& lhs, PointType const& rhs) const
+    {
+        coordinate_type const& left0 = ggl::get<0>(lhs);
+        coordinate_type const& right0 = ggl::get<0>(rhs);
+
+        return ggl::math::equals(left0, right0)
+            ? ggl::get<1>(lhs) < ggl::get<1>(rhs)
+            : left0 < right0;
+    }
+};
+
+
+
+// T can be an intersection_point or intersection_info record
+template <typename T>
+struct is_flagged
+{
+    inline bool operator()(T const& object) const
+    {
+        return object.flagged;
+    }
+};
+
+
+
+template <typename V>
+inline void remove_collinearities(V& intersection_points)
+{
+    typedef typename boost::range_iterator<V>::type iterator_type;
+    typedef typename boost::range_value<V>::type ip_type;
+    typedef typename ip_type::traversal_type info_type;
+
+
+    for (iterator_type it = boost::begin(intersection_points);
+         it != boost::end(intersection_points);
+         ++it)
+    {
+        if (! it->trivial && ! it->flagged)
+        {
+            // Remove anything having to do with collinearity
+            typedef typename boost::range_value<V>::type::traversal_vector vector_type;
+            typedef typename boost::range_iterator<vector_type>::type tvit_type;
+
+            bool has_flag = false;
+
+            // Note, this is done n*m, in case of collinearity, but it is only done if not trivial
+            bool middle = false;
+            for (tvit_type tvit = boost::begin(it->info);
+                ! middle && tvit != boost::end(it->info);
+                ++tvit)
+            {
+                if (tvit->how == 'e' || tvit->how == 'c')
+                {
+                    tvit->flagged = true;
+                    has_flag = true;
+
+                    for (tvit_type tvit2 = boost::begin(it->info);
+                        tvit2 != boost::end(it->info);
+                        ++tvit2)
+                    {
+                        // Do NOT remove anything starting from collinear, or ending on, in the middle.
+                        if (tvit2->how != 'm' && tvit2->how != 's')
+                        {
+                            if (tvit->seg_id == tvit2->seg_id
+                                || tvit->seg_id == tvit2->other_id
+                                || tvit->other_id == tvit2->seg_id
+                                || tvit->other_id == tvit2->other_id
+                                )
+                            {
+                                tvit2->flagged = true;
+                            }
+                        }
+                        else
+                        {
+                            tvit->flagged = false;
+                            has_flag = false;
+                            middle = true;
+                        }
+                    }
+                }
+            }
+
+            if (has_flag)
+            {
+                it->info.erase(
+                    std::remove_if(
+                            boost::begin(it->info),
+                            boost::end(it->info),
+                            is_flagged<info_type>()),
+                    boost::end(it->info));
+
+                // Mark for deletion afterwards if there are no info-records left
+                if (boost::size(it->info) == 0)
+                {
+                    it->flagged = true;
+                }
+
+                // Some cases will be normal (neutral) case now,
+                // so to continue traversal.
+                if (it->info.size() == 2)
+                {
+                    // Case: previously forming an 'angle' (test #19)
+                    if (it->info.front().how == 'a'
+                            && it->info.back().how == 'a')
+                    {
+                        it->info.front().direction = 1;
+                        it->info.back().direction = 1;
+                    }
+                    // Case: both arrive there, they can continue,
+                    // change in departure
+                    if (it->info.front().how == 't'
+                            && it->info.back().how == 't')
+                    {
+                        it->info.front().arrival = -1;
+                        it->info.back().arrival = -1;
+                    }
+                }
+            }
+        }
+    }
+
+#ifdef GGL_DEBUG_INTERSECTION
+    std::cout << "Removed collinearities: " << std::endl;
+    report_ip(intersection_points);
+#endif
+}
+
+
+
+
+
+}} // namespace detail::intersection
+#endif //DOXYGEN_NO_DETAIL
+
+
+
+/*!
+    \brief Merges intersection points such that points at the same location will be merged, having one point
+        and their info-records appended
+    \ingroup overlay
+    \tparam IntersectionPoints type of intersection container (e.g. vector of "intersection_point"'s)
+    \param intersection_points container containing intersectionpoints
+ */
+template <typename IntersectionPoints>
+inline void merge_intersection_points(IntersectionPoints& intersection_points)
+{
+    typedef typename boost::range_value<IntersectionPoints>::type trav_type;
+
+    if (boost::size(intersection_points) <= 1)
+    {
+        return;
+    }
+
+
+    // Sort all IP's from left->right, ymin->ymax such that
+    // all same IP's are consecutive
+    // (and we need this order lateron again)
+    // This order is NOT changed here and should not be after
+    // (otherwise indexes are wrong)
+    std::sort(boost::begin(intersection_points),
+        boost::end(intersection_points),
+        detail::intersection::on_increasing_dimension<trav_type>());
+
+    typedef typename boost::range_iterator<IntersectionPoints>::type iterator;
+
+#ifdef GGL_DEBUG_INTERSECTION
+    std::cout << "Sorted (x then y): " << std::endl;
+    for (iterator it = boost::begin(intersection_points);
+        it != boost::end(intersection_points); ++it)
+    {
+        std::cout << *it;
+    }
+#endif
+    bool has_merge = false;
+
+    // Merge all same IP's, combining there IP/segment-info entries
+    iterator it = boost::begin(intersection_points);
+    for (iterator prev = it++; it != boost::end(intersection_points); ++it)
+    {
+        // IP can be merged if the point is equal
+        if (ggl::detail::equals::equals_point_point(prev->point, it->point))
+        {
+            has_merge = true;
+            prev->shared = true;
+            prev->trivial = false;
+            it->flagged = true;
+            std::copy(it->info.begin(), it->info.end(),
+                        std::back_inserter(prev->info));
+        }
+        else
+        {
+            prev = it;
+        }
+    }
+
+
+    if (has_merge)
+    {
+#ifdef GGL_DEBUG_INTERSECTION
+        std::cout << "Merged (1): " << std::endl;
+        report_ip(intersection_points);
+#endif
+
+        // If there merges, there might be  collinearities
+        detail::intersection::remove_collinearities(intersection_points);
+
+        // Remove all IP's which are flagged for deletion
+        intersection_points.erase(
+            std::remove_if(
+                    boost::begin(intersection_points),
+                    boost::end(intersection_points),
+                    detail::intersection::is_flagged<trav_type>()),
+            boost::end(intersection_points));
+
+
+#ifdef GGL_DEBUG_INTERSECTION
+        std::cout << "Merged (2): " << std::endl;
+        report_ip(intersection_points);
+#endif
+
+
+    }
+
+}
+
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_OVERLAY_MERGE_INTERSECTION_POINTS_HPP
Added: sandbox/ggl/formal_review/boost/ggl/algorithms/overlay/segment_identifier.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/algorithms/overlay/segment_identifier.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,85 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_OVERLAY_SEGMENT_IDENTIFIER_HPP
+#define GGL_ALGORITHMS_OVERLAY_SEGMENT_IDENTIFIER_HPP
+
+#include <vector>
+
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/coordinate_dimension.hpp>
+
+#include <ggl/strategies/distance_result.hpp>
+
+namespace ggl
+{
+
+
+// Internal struct to uniquely identify a segment
+// on a linestring,ring
+// or polygon (needs ring_index)
+// or multi-geometry (needs multi_index)
+struct segment_identifier
+{
+    inline segment_identifier()
+        : source_index(-1)
+        , multi_index(-1)
+        , ring_index(-1)
+        , segment_index(-1)
+    {}
+
+    inline segment_identifier(int src, int mul, int rin, int seg)
+        : source_index(src)
+        , multi_index(mul)
+        , ring_index(rin)
+        , segment_index(seg)
+    {}
+
+    inline bool operator<(segment_identifier const& other) const
+    {
+        return source_index != other.source_index ? source_index < other.source_index
+            : multi_index !=other.multi_index ? multi_index < other.multi_index
+            : ring_index != other.ring_index ? ring_index < other.ring_index
+            : segment_index < other.segment_index
+            ;
+    }
+
+    inline bool operator==(segment_identifier const& other) const
+    {
+        return source_index == other.source_index
+            && segment_index == other.segment_index
+            && ring_index == other.ring_index
+            && multi_index == other.multi_index
+            ;
+    }
+
+#ifdef GGL_DEBUG_INTERSECTION
+    friend std::ostream& operator<<(std::ostream &os, segment_identifier const& seg_id)
+    {
+        std::cout
+            << "s:" << seg_id.source_index
+            << ", v:" << seg_id.segment_index // vertex
+            ;
+        if (seg_id.ring_index >= 0) std::cout << ", r:" << seg_id.ring_index;
+        if (seg_id.multi_index >= 0) std::cout << ", m:" << seg_id.multi_index;
+        return os;
+    }
+#endif
+
+    int source_index;
+    int multi_index;
+    int ring_index;
+    int segment_index;
+};
+
+
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_OVERLAY_SEGMENT_IDENTIFIER_HPP
Added: sandbox/ggl/formal_review/boost/ggl/algorithms/overlay/self_intersection_points.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/algorithms/overlay/self_intersection_points.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,173 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_OVERLAY_SELF_INTERSECTION_POINTS_HPP
+#define GGL_ALGORITHMS_OVERLAY_SELF_INTERSECTION_POINTS_HPP
+
+#include <cstddef>
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/coordinate_dimension.hpp>
+#include <ggl/core/is_multi.hpp>
+
+#include <ggl/geometries/concepts/check.hpp>
+
+#include <ggl/algorithms/detail/disjoint.hpp>
+#include <ggl/algorithms/overlay/get_intersection_points.hpp>
+
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace self_intersection_points {
+
+template
+<
+    typename Geometry,
+    typename IntersectionPoints
+>
+struct check_ips
+{
+    static inline bool apply(
+            Geometry const& geometry,
+            bool return_if_found,
+            IntersectionPoints& intersection_points)
+    {
+        typedef typename ggl::sections
+            <
+                ggl::box < typename ggl::point_type<Geometry>::type >, 1
+            > sections_type;
+
+        sections_type sec;
+        ggl::sectionalize(geometry, sec);
+
+        bool trivial = true;
+        for (typename boost::range_const_iterator<sections_type>::type
+                    it1 = sec.begin();
+            it1 != sec.end();
+            ++it1)
+        {
+            for (typename boost::range_const_iterator<sections_type>::type
+                        it2 = sec.begin();
+                it2 != sec.end();
+                ++it2)
+            {
+                if (! ggl::detail::disjoint::disjoint_box_box(
+                                it1->bounding_box, it2->bounding_box)
+                    && ! it1->duplicate
+                    && ! it2->duplicate
+                    )
+                {
+                    ggl::detail::get_intersection_points::get_ips_in_sections
+                    <
+                        Geometry, Geometry,
+                        typename boost::range_value<sections_type>::type,
+                        typename boost::range_value<sections_type>::type,
+                        IntersectionPoints
+                    >::apply(
+                            0, geometry, *it1,
+                            0, geometry, *it2,
+                            return_if_found,
+                            intersection_points, trivial);
+                }
+            }
+        }
+        return trivial;
+    }
+};
+
+
+}} // namespace detail::self_intersection_points
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+    typename GeometryTag,
+    bool IsMulti,
+    typename Geometry,
+    typename IntersectionPoints
+
+>
+struct self_intersection_points
+{
+};
+
+
+template<typename Ring, typename IntersectionPoints>
+struct self_intersection_points
+    <
+        ring_tag, false, Ring,
+        IntersectionPoints
+    >
+    : detail::self_intersection_points::check_ips
+        <
+            Ring,
+            IntersectionPoints
+        >
+{};
+
+
+template<typename Polygon, typename IntersectionPoints>
+struct self_intersection_points
+    <
+        polygon_tag, false, Polygon,
+        IntersectionPoints
+    >
+    : detail::self_intersection_points::check_ips
+        <
+            Polygon,
+            IntersectionPoints
+        >
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+    \brief Calculate self intersections of a geometry
+    \ingroup overlay
+    \tparam Geometry geometry type
+    \tparam IntersectionPoints type of intersection container (e.g. vector of "intersection_point"'s)
+    \param geometry geometry
+    \param intersection_points container which will contain intersection points
+    \return TRUE if it is trivial, else FALSE
+ */
+template <typename Geometry, typename IntersectionPoints>
+inline bool get_intersection_points(Geometry const& geometry,
+            IntersectionPoints& intersection_points)
+{
+    concept::check<Geometry>();
+
+    typedef typename boost::remove_const<Geometry>::type ncg_type;
+
+    return dispatch::self_intersection_points
+            <
+                typename tag<ncg_type>::type,
+                is_multi<ncg_type>::type::value,
+                ncg_type,
+               IntersectionPoints
+            >::apply(geometry, false, intersection_points);
+}
+
+
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_OVERLAY_SELF_INTERSECTION_POINTS_HPP
Added: sandbox/ggl/formal_review/boost/ggl/algorithms/overlay/sort_interior_rings.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/algorithms/overlay/sort_interior_rings.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,128 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_OVERLAY_SORT_INTERIOR_RINGS_HPP
+#define GGL_ALGORITHMS_OVERLAY_SORT_INTERIOR_RINGS_HPP
+
+#include <algorithm>
+#include <vector>
+
+#include <ggl/algorithms/area.hpp>
+#include <ggl/algorithms/within.hpp>
+#include <ggl/algorithms/detail/point_on_border.hpp>
+
+namespace ggl
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace overlay {
+
+struct sortable
+{
+    int index; // zero-based (ZB) index to ring in rings
+    double area;
+    int index_of_parent; // ZB index to parent-ring
+    std::vector<int> index_of_holes; // ZB index to holes
+
+    inline sortable(int i, double a)
+        : index(i)
+        , area(a)
+        , index_of_parent(-1)
+    {}
+
+    inline bool operator<(sortable const& other) const
+    {
+        // sort in reverse order
+        return area > other.area;
+    }
+};
+
+
+
+template<typename Container>
+void sort_interior_rings(Container const& rings, std::vector<sortable>& sorted_rings, int factor)
+{
+    typedef typename boost::range_value<Container>::type ring_type;
+    typedef typename ggl::point_type<ring_type>::type point_type;
+
+    // Because of the whole followed procedure, the orientations (cw or ccw)
+    // of parents and holes are OK, and their areas are positive (parents)
+    // or negative (children)
+
+    // Create a copy (without copying geometries), with area (and envelope)
+    std::size_t n = 0;
+    for (typename boost::range_const_iterator<Container>::type
+            it = boost::begin(rings);
+        it != boost::end(rings);
+        ++it, ++n)
+    {
+        sorted_rings.push_back(sortable(n, factor * ggl::area(*it)));
+    }
+
+    // Sort in reverse order -> largest rings first, holes (neg. area) last
+    std::sort(sorted_rings.begin(), sorted_rings.end());
+
+    // Check which holes are in which polygons
+    for (std::size_t hole = 1; hole < n; hole++)
+    {
+        // It is a hole if its area is negative
+        if (sorted_rings[hole].area < 0 || factor < 0)
+        {
+            // So check if it is lying in one of the earlier rings
+            bool parent_found = false;
+            for (std::size_t parent = 0;
+                    parent < hole
+                        && ! parent_found
+                        && sorted_rings[parent].area > 0;
+                    parent++)
+            {
+                // note that "hole"  is indexed in sorted rings,
+                // so make new "h" that is indexed in original rings
+                int const h = sorted_rings[hole].index;
+                int const p = sorted_rings[parent].index;
+
+                point_type point;
+                ggl::point_on_border(rings[h], point);
+                if (ggl::within(point, rings[p]))
+                {
+                    // Update registration
+                    sorted_rings[hole].index_of_parent = p;
+                    sorted_rings[parent].index_of_holes.push_back(h);
+                    parent_found = true;
+                }
+            }
+        }
+    }
+
+    /***
+    for (std::size_t i = 0; i < n; i++)
+    {
+        std::cout << "i: " << i
+            << " area: " << sorted_rings[i].area
+            << " count: " << rings[sorted_rings[i].index].size()
+            << " parent: " << sorted_rings[i].index_of_parent
+            << " holes: ";
+        for (int j = 0; j < boost::size(sorted_rings[i].index_of_holes); j++)
+        {
+            std::cout << " " << sorted_rings[i].index_of_holes[j];
+        }
+        std::cout << std::endl;
+    }
+    ***/
+}
+
+
+
+}} // namespace detail::overlay
+#endif //DOXYGEN_NO_DETAIL
+
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_OVERLAY_SORT_INTERIOR_RINGS_HPP
Added: sandbox/ggl/formal_review/boost/ggl/algorithms/overlay/traverse.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/algorithms/overlay/traverse.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,437 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_OVERLAY_TRAVERSE_HPP
+#define GGL_ALGORITHMS_OVERLAY_TRAVERSE_HPP
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/coordinate_dimension.hpp>
+
+#include <ggl/algorithms/overlay/copy_segments.hpp>
+
+#include <ggl/strategies/side.hpp>
+
+#include <ggl/geometries/concepts/check.hpp>
+
+#ifdef GGL_DEBUG_INTERSECTION
+#include <ggl/extensions/gis/io/wkt/write_wkt.hpp>
+#endif
+
+
+namespace ggl
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace intersection {
+
+
+const int VISIT_NONE = 0;
+const int VISIT_START = 1;
+const int VISIT_VISITED = 2;
+const int VISIT_FINISH = 3;
+const int VISIT_WITHIN = 4;
+
+
+template
+<
+    typename IntersectionPoint,
+    typename IntersectionInfo
+>
+struct on_direction
+{
+    typedef typename strategy_side
+        <
+            typename cs_tag<IntersectionPoint>::type
+        >::type side;
+
+    inline on_direction(IntersectionPoint const& ip, int direction)
+        : m_ip(ip)
+        , m_direction(direction)
+    {}
+
+
+    inline bool operator()(IntersectionInfo const& first, IntersectionInfo const& second) const
+    {
+        int dir = side::apply(m_ip, first->other_point, second->other_point);
+        return m_direction == dir;
+    }
+
+private :
+    IntersectionPoint const& m_ip;
+    int m_direction;
+};
+
+
+template
+<
+    typename GeometryOut,
+    typename G1,
+    typename G2,
+    typename IntersectionPoints,
+    typename IntersectionInfo
+>
+inline bool assign_next_ip(G1 const& g1, G2 const& g2, int direction,
+            IntersectionPoints& intersection_points,
+            typename boost::range_iterator<IntersectionPoints>::type & ip,
+            GeometryOut& current_output,
+            IntersectionInfo & info)
+{
+    info.visit_code = VISIT_VISITED;
+
+#ifdef GGL_DEBUG_INTERSECTION
+    std::cout << " take: " << info << std::endl;
+#endif
+
+    // If there is no next IP on this segment
+    if (info.next_ip_index < 0)
+    {
+        if (info.seg_id.source_index == 0)
+        {
+            ggl::copy_segments(g1, info.seg_id,
+                    info.travels_to_vertex_index,
+                    current_output);
+        }
+        else
+        {
+            ggl::copy_segments(g2, info.seg_id,
+                    info.travels_to_vertex_index,
+                    current_output);
+        }
+        ip = boost::begin(intersection_points) + info.travels_to_ip_index;
+    }
+    else
+    {
+        ip = boost::begin(intersection_points) + info.next_ip_index;
+    }
+    current_output.push_back(ip->point);
+
+    return true;
+}
+
+template <typename Info>
+inline bool turning(Info const& info, int direction)
+{
+    // If it is turning in specified direction (RIGHT for intersection,
+    // LEFT for union, and NOT arriving at that point
+    return info.direction == direction
+        && info.arrival != 1
+        //&& (! (info.how == 'a' && info.direction != 0))
+        ;
+}
+
+template
+<
+    typename GeometryOut,
+    typename G1,
+    typename G2,
+    typename IntersectionPoints
+>
+inline bool select_next_ip_trivial(G1 const& g1, G2 const& g2, int direction,
+            IntersectionPoints& intersection_points,
+            typename boost::range_iterator<IntersectionPoints>::type & ip,
+            GeometryOut& current_output)
+{
+    // Check all intersecting segments on this IP:
+    typedef typename boost::range_value<IntersectionPoints>::type ip_type;
+    typedef typename ip_type::traversal_vector tv;
+    typedef typename boost::range_iterator<tv>::type tit_type;
+
+    for (tit_type it = boost::begin(ip->info); it != boost::end(ip->info); ++it)
+    {
+        if (turning(*it, direction))
+        {
+            return assign_next_ip(g1, g2, direction,
+                        intersection_points, ip, current_output, *it);
+        }
+    }
+
+    return false;
+}
+
+
+template
+<
+    typename GeometryOut,
+    typename G1,
+    typename G2,
+    typename IntersectionPoints
+>
+inline bool select_next_ip_with_sorting(G1 const& g1, G2 const& g2,
+            int direction,
+            IntersectionPoints& intersection_points,
+            typename boost::range_iterator<IntersectionPoints>::type & ip,
+            GeometryOut& current_output)
+{
+
+    typedef typename boost::range_value<IntersectionPoints>::type ip_type;
+    typedef typename ip_type::traversal_vector tv;
+    typedef typename boost::range_iterator<tv>::type tit_type;
+    typedef typename ip_type::traversal_type info_type;
+
+    std::vector<info_type*> info;
+    for (tit_type it = boost::begin(ip->info); it != boost::end(ip->info); ++it)
+    {
+        if (turning(*it, direction))
+        {
+            info.push_back(&(*it));
+        }
+    }
+
+    // If there are no intersection points, fall-back to collinear cases or
+    // if already in that case, return false.
+    if (boost::size(info) == 0)
+    {
+        return direction == 0
+            ? false
+            : select_next_ip_with_sorting(g1, g2, 0,
+                            intersection_points, ip, current_output);
+    }
+
+    // For one IP, it is easy: take that one.
+    if (boost::size(info) == 1)
+    {
+        return assign_next_ip(g1, g2, direction,
+                    intersection_points, ip, current_output, *info.front());
+    }
+
+    // In case of direction 0, also take first one
+    // TODO: sort this vector somehow, there are more rows, it is too
+    // arbitrary to take first one (though working well)
+    if (direction == 0)
+    {
+        return assign_next_ip(g1, g2, direction,
+                    intersection_points, ip, current_output, *info.front());
+    }
+
+
+    // For more, sort the information on direction, take the most left / right one
+    //std::cout << " " << boost::size(info);
+    std::sort(info.begin(), info.end(), on_direction<ip_type, info_type*>(*ip, direction));
+    return assign_next_ip(g1, g2, direction, intersection_points, ip, current_output, *info.back());
+}
+
+template
+<
+    typename GeometryOut,
+    typename G1,
+    typename G2,
+    typename IntersectionPoints
+>
+inline bool select_next_ip(G1 const& g1, G2 const& g2, int direction,
+            IntersectionPoints& intersection_points,
+            typename boost::range_iterator<IntersectionPoints>::type & ip,
+            GeometryOut& current_output)
+{
+    if (ip->trivial)
+    {
+        return select_next_ip_trivial(g1, g2, direction, intersection_points,
+                ip, current_output);
+    }
+    else
+    {
+        return select_next_ip_with_sorting(g1, g2, direction, intersection_points,
+                ip, current_output);
+    }
+}
+
+
+template<typename IntersectionPoint>
+inline bool is_starting_point(IntersectionPoint const& ip, int direction)
+{
+    for (typename IntersectionPoint::traversal_vector::const_iterator it
+        = boost::begin(ip.info); it != boost::end(ip.info); ++it)
+    {
+        if (it->direction == direction
+            && it->arrival != 1)
+        {
+            return true;
+        }
+    }
+    return false;
+}
+
+
+template <typename Container>
+inline void stop_gracefully(Container& container, bool& stop,
+            std::string const& reason)
+{
+#ifdef GGL_DEBUG_INTERSECTION
+    std::cout << "STOPPING: " << reason << std::endl;
+#endif
+
+    stop = true;
+    if (container.size() > 0)
+    {
+        container.push_back(container.front());
+    }
+}
+
+}} // namespace detail::intersection
+#endif // DOXYGEN_NO_DETAIL
+
+
+
+
+
+
+/*!
+    \brief Traverses through intersection points / geometries
+    \ingroup overlay
+ */
+template
+<
+    typename GeometryOut,
+    typename Geometry1,
+    typename Geometry2,
+    typename IntersectionPoints,
+    typename OutputIterator
+>
+inline void traverse(Geometry1 const& geometry1,
+            Geometry2 const& geometry2, int direction,
+            IntersectionPoints& intersection_points,
+            bool trivial,
+            OutputIterator out)
+{
+    concept::check<const Geometry1>();
+    concept::check<const Geometry2>();
+
+
+    typedef typename boost::range_iterator
+                <IntersectionPoints>::type ip_iterator;
+
+    typedef typename boost::range_value<IntersectionPoints>::type ip_type;
+    typedef typename ip_type::traversal_vector tv;
+    typedef typename boost::range_iterator<tv>::type tit_type;
+    typedef typename ip_type::traversal_type info_type;
+
+
+
+    GeometryOut current_output;
+
+
+    // Iterate through all unvisited points
+    for (ip_iterator it = boost::begin(intersection_points);
+        it != boost::end(intersection_points);
+        ++it)
+    {
+#ifdef GGL_DEBUG_INTERSECTION
+        std::cout << "TRY traversal: " << *it;
+#endif
+
+        if (it->visit_code == detail::intersection::VISIT_NONE
+            // UNION may operate on non-starting points, but INTERSECTION may not.
+            // TODO: re-evaluate that
+            && (direction == 1
+            || detail::intersection::is_starting_point(*it, direction)
+                )
+            )
+        {
+            for (tit_type iit = boost::begin(it->info);
+                iit != boost::end(it->info);
+                ++iit)
+            {
+                if (iit->arrival == -1
+                    && iit->visit_code == detail::intersection::VISIT_NONE
+                    && iit->direction == direction)
+                {
+                    it->visit_code = detail::intersection::VISIT_START;
+                    iit->visit_code = detail::intersection::VISIT_START;
+
+                    current_output.push_back(it->point);
+
+                    ip_iterator current = it;
+
+#ifdef GGL_DEBUG_INTERSECTION
+                    std::cout << "START traversal: " << *current;
+#endif
+
+                    detail::intersection::assign_next_ip(geometry1, geometry2,
+                                direction,
+                                intersection_points,
+                                current, current_output, *iit);
+
+                    std::vector<segment_identifier> segments;
+                    segments.push_back(iit->seg_id);
+
+                    unsigned int i = 0;
+                    bool stop = false;
+
+                    while (current != it && ! stop)
+                    {
+#ifdef GGL_DEBUG_INTERSECTION
+                        std::cout << "traverse: " << *current;
+#endif
+
+                        // We assume clockwise polygons only, non self-intersecting, closed.
+                        // However, the input might be different, and checking validity
+                        // is up to the library user.
+
+                        // Therefore we make here some sanity checks. If the input
+                        // violates the assumptions, the output polygon will not be correct
+                        // but the routine will stop and output the current polygon, and
+                        // will continue with the next one.
+
+                        // Below three reasons to stop.
+                        if (! detail::intersection::select_next_ip(geometry1,
+                                    geometry2, direction,
+                                    intersection_points,
+                                    current, current_output))
+                        {
+                            // Should not occur in valid (non-self-intersecting) polygons
+                            // Should not occur in self-intersecting polygons without spikes
+                            // Might occur in polygons with spikes
+                            detail::intersection::stop_gracefully(
+                                current_output, stop, "Dead end");
+                        }
+
+                        if (current->visit_code == detail::intersection::VISIT_VISITED)
+                        {
+                            // It visits a visited node again, without passing the start node.
+                            // This makes it suspicious for endless loops
+                            // Check if it is really same node
+                            detail::intersection::stop_gracefully(
+                                current_output, stop, "Visit again");
+                        }
+
+
+                        if (i++ > intersection_points.size())
+                        {
+                            // Sanity check: there may be never more loops
+                            // than intersection points.
+                            detail::intersection::stop_gracefully(
+                                current_output, stop, "Endless loop");
+                        }
+
+                        current->visit_code = detail::intersection::VISIT_VISITED;
+                    }
+
+                    iit->visit_code = detail::intersection::VISIT_FINISH;
+
+#ifdef GGL_DEBUG_INTERSECTION
+                    std::cout << "finish: " << *current;
+                    std::cout << ggl::wkt(current_output) << std::endl;
+#endif
+
+                    *out = current_output;
+                    ++out;
+                    current_output.clear();
+                }
+            }
+            it->visit_code = detail::intersection::VISIT_FINISH;
+        }
+    }
+}
+
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_OVERLAY_TRAVERSE_HPP
Added: sandbox/ggl/formal_review/boost/ggl/algorithms/parse.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/algorithms/parse.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,122 @@
+// Generic Geometry Library
+//
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_PARSE_HPP
+#define GGL_ALGORITHMS_PARSE_HPP
+
+#include <string>
+
+
+#include <ggl/core/tags.hpp>
+#include <ggl/strategies/parse.hpp>
+
+#include <ggl/geometries/concepts/check.hpp>
+
+// TODO: remove used EXTENSION here (result should be part of parsing strategy)
+#include <ggl/extensions/gis/geographic/strategies/dms_parser.hpp>
+
+/*!
+\defgroup parse parse and assign string values
+*/
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+template <typename Tag, typename G>
+struct parsing
+{
+};
+
+template <typename Point>
+struct parsing<point_tag, Point>
+{
+    template <typename S>
+    static inline void parse(Point& point, std::string const& c1, std::string const& c2, S const& strategy)
+    {
+        assert_dimension<Point, 2>();
+        dms_result r1 = strategy(c1.c_str());
+        dms_result r2 = strategy(c2.c_str());
+
+        if (0 == r1.axis())
+            set<0>(point, r1);
+        else
+            set<1>(point, r1);
+
+        if (0 == r2.axis())
+            set<0>(point, r2);
+        else
+            set<1>(point, r2);
+    }
+
+    static inline void parse(Point& point, std::string const& c1, std::string const& c2)
+    {
+        // strategy-parser corresponding to degree/radian
+        typename strategy_parse
+            <
+            typename cs_tag<Point>::type,
+            typename coordinate_system<Point>::type
+            >::type strategy;
+
+        parse(point, c1, c2, strategy);
+    }
+};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+    \brief parse two strings to a spherical/geographic point, using W/E/N/S
+    \ingroup parse
+ */
+template <typename Geometry>
+inline void parse(Geometry& geometry, std::string const& c1, std::string const& c2)
+{
+    concept::check<Geometry>();
+    dispatch::parsing<typename tag<Geometry>::type, Geometry>::parse(geometry, c1, c2);
+}
+
+/*!
+    \brief parse two strings to a spherical/geographic point, using a specified strategy
+    \details user can use N/E/S/O or N/O/Z/W or other formats
+    \ingroup parse
+ */
+template <typename Geometry, typename S>
+inline void parse(Geometry& geometry, std::string const& c1,
+        std::string const& c2, S const& strategy)
+{
+    concept::check<Geometry>();
+    dispatch::parsing<typename tag<Geometry>::type, Geometry>::parse(geometry, c1, c2, strategy);
+}
+
+// There will be a parsing function with three arguments (ANGLE,ANGLE,RADIUS)
+
+template <typename Geometry>
+inline Geometry parse(std::string const& c1, std::string const& c2)
+{
+    concept::check<Geometry>();
+
+    Geometry geometry;
+    dispatch::parsing<typename tag<Geometry>::type, Geometry>::parse(geometry, c1, c2);
+    return geometry;
+}
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_PARSE_HPP
Added: sandbox/ggl/formal_review/boost/ggl/algorithms/perimeter.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/algorithms/perimeter.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,137 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_PERIMETER_HPP
+#define GGL_ALGORITHMS_PERIMETER_HPP
+
+
+#include <ggl/core/cs.hpp>
+
+#include <ggl/geometries/concepts/check.hpp>
+
+#include <ggl/strategies/length_result.hpp>
+
+#include <ggl/algorithms/length.hpp>
+#include <ggl/algorithms/detail/calculate_null.hpp>
+#include <ggl/algorithms/detail/calculate_sum.hpp>
+
+
+/*!
+\defgroup perimeter perimeter: calculate perimeter of a geometry
+\par Geometries:
+- \b polygon
+- \b box
+- \b linear_ring
+- \b multi_polygon
+*/
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+// Default perimeter is 0.0, specializations implement calculated values
+template <typename Tag, typename Geometry, typename Strategy>
+struct perimeter : detail::calculate_null
+    <
+        typename length_result<Geometry>::type,
+        Geometry,
+        Strategy
+    >
+{};
+
+template <typename Geometry, typename Strategy>
+struct perimeter<ring_tag, Geometry, Strategy>
+    : detail::length::range_length<Geometry, Strategy>
+{};
+
+template <typename Polygon, typename Strategy>
+struct perimeter<polygon_tag, Polygon, Strategy>
+    : detail::calculate_polygon_sum
+        <
+            typename length_result<Polygon>::type,
+            Polygon,
+            Strategy,
+            detail::length::range_length
+                <
+                    typename ring_type<Polygon>::type,
+                    Strategy
+                >
+        >
+{};
+
+
+// box,n-sphere: to be implemented
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+    \brief Calculate perimeter of a geometry
+    \ingroup perimeter
+    \details The function perimeter returns the perimeter of a geometry,
+        using the default distance-calculation-strategy
+    \param geometry the geometry, be it a ggl::ring, vector, iterator pair,
+        or any other boost compatible range
+    \return the perimeter
+ */
+template<typename Geometry>
+inline typename length_result<Geometry>::type perimeter(
+        Geometry const& geometry)
+{
+    concept::check<const Geometry>();
+
+    typedef typename point_type<Geometry>::type point_type;
+    typedef typename cs_tag<point_type>::type cs_tag;
+    typedef typename strategy_distance
+        <
+            cs_tag,
+            cs_tag,
+            point_type,
+            point_type
+        >::type strategy_type;
+
+    return dispatch::perimeter
+        <
+            typename tag<Geometry>::type,
+            Geometry,
+            strategy_type
+        >::apply(geometry, strategy_type());
+}
+
+/*!
+    \brief Calculate perimeter of a geometry
+    \ingroup perimeter
+    \details The function perimeter returns the perimeter of a geometry,
+        using specified strategy
+    \param geometry the geometry, be it a ggl::ring, vector, iterator pair,
+        or any other boost compatible range
+    \param strategy strategy to be used for distance calculations.
+    \return the perimeter
+ */
+template<typename Geometry, typename Strategy>
+inline typename length_result<Geometry>::type perimeter(
+        Geometry const& geometry, Strategy const& strategy)
+{
+    concept::check<const Geometry>();
+
+    return dispatch::perimeter
+        <
+            typename tag<Geometry>::type,
+            Geometry,
+            Strategy
+        >::apply(geometry, strategy);
+}
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_PERIMETER_HPP
+
Added: sandbox/ggl/formal_review/boost/ggl/algorithms/sectionalize.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/algorithms/sectionalize.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,581 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_SECTIONALIZE_HPP
+#define GGL_ALGORITHMS_SECTIONALIZE_HPP
+
+#include <cstddef>
+#include <vector>
+
+#include <boost/concept_check.hpp>
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/algorithms/assign.hpp>
+#include <ggl/algorithms/combine.hpp>
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/exterior_ring.hpp>
+
+#include <ggl/geometries/concepts/check.hpp>
+
+
+#include <ggl/util/math.hpp>
+#include <ggl/geometries/segment.hpp>
+
+
+/*!
+\defgroup sectionalize sectionalize: split a geometry (polygon, linestring, etc)
+    into monotonic sections
+
+\par Geometries:
+- LINESTRING:
+- RING:
+- POLYGON:
+- BOX
+*/
+
+namespace ggl
+{
+
+
+/*!
+    \brief Structure containing section information
+    \details Section information consists of a bounding box, direction
+        information (if it is increasing or decreasing, per dimension),
+        index information (begin-end, ring, multi) and the number of
+        segments in this section
+
+    \tparam Box box-type
+    \tparam DimensionCount number of dimensions for this section
+    \ingroup sectionalize
+ */
+template <typename Box, std::size_t DimensionCount>
+struct section
+{
+    typedef Box box_type;
+
+    int directions[DimensionCount];
+    int ring_index;
+    int multi_index;
+    Box bounding_box;
+
+    int begin_index;
+    int end_index;
+    std::size_t count;
+    std::size_t range_count;
+    bool duplicate;
+    int non_duplicate_index;
+
+
+    inline section()
+        : ring_index(-99)
+        , multi_index(-99)
+        , begin_index(-1)
+        , end_index(-1)
+        , count(0)
+        , range_count(0)
+        , duplicate(false)
+        , non_duplicate_index(-1)
+    {
+        assign_inverse(bounding_box);
+        for (register std::size_t i = 0; i < DimensionCount; i++)
+        {
+            directions[i] = 0;
+        }
+    }
+};
+
+
+/*!
+    \brief Structure containing a collection of sections
+    \note Derived from a vector, proves to be faster than of deque
+    \note vector might be templated in the future
+    \ingroup sectionalize
+ */
+template <typename Box, std::size_t DimensionCount>
+struct sections : std::vector<section<Box, DimensionCount> >
+{
+    typedef Box box_type;
+    static const std::size_t value = DimensionCount;
+};
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace sectionalize {
+
+template <typename Segment, std::size_t Dimension, std::size_t DimensionCount>
+struct get_direction_loop
+{
+    typedef typename coordinate_type<Segment>::type coordinate_type;
+
+    static inline void apply(Segment const& seg,
+                int directions[DimensionCount])
+    {
+        coordinate_type const diff =
+            ggl::get<1, Dimension>(seg) - ggl::get<0, Dimension>(seg);
+
+        directions[Dimension] = diff > 0 ? 1 : (diff < 0 ? -1 : 0);
+
+        get_direction_loop
+            <
+                Segment, Dimension + 1, DimensionCount
+            >::apply(seg, directions);
+    }
+};
+
+template <typename Segment, std::size_t DimensionCount>
+struct get_direction_loop<Segment, DimensionCount, DimensionCount>
+{
+    static inline void apply(Segment const& seg,
+                int directions[DimensionCount])
+    {
+        boost::ignore_unused_variable_warning(seg);
+        boost::ignore_unused_variable_warning(directions);
+    }
+};
+
+template <typename T, std::size_t Dimension, std::size_t DimensionCount>
+struct copy_loop
+{
+    static inline void apply(const T source[DimensionCount],
+                T target[DimensionCount])
+    {
+        target[Dimension] = source[Dimension];
+        copy_loop<T, Dimension + 1, DimensionCount>::apply(source, target);
+    }
+};
+
+template <typename T, std::size_t DimensionCount>
+struct copy_loop<T, DimensionCount, DimensionCount>
+{
+    static inline void apply(const T source[DimensionCount],
+                T target[DimensionCount])
+    {
+        boost::ignore_unused_variable_warning(source);
+        boost::ignore_unused_variable_warning(target);
+    }
+};
+
+template <typename T, std::size_t Dimension, std::size_t DimensionCount>
+struct compare_loop
+{
+    static inline bool apply(const T source[DimensionCount],
+                const T target[DimensionCount])
+    {
+        bool const not_equal = target[Dimension] != source[Dimension];
+
+        return not_equal
+            ? false
+            : compare_loop
+                <
+                    T, Dimension + 1, DimensionCount
+                >::apply(source, target);
+    }
+};
+
+template <typename T, std::size_t DimensionCount>
+struct compare_loop<T, DimensionCount, DimensionCount>
+{
+    static inline bool apply(const T source[DimensionCount],
+                const T target[DimensionCount])
+    {
+        boost::ignore_unused_variable_warning(source);
+        boost::ignore_unused_variable_warning(target);
+
+        return true;
+    }
+};
+
+
+template <typename Segment, std::size_t Dimension, std::size_t DimensionCount>
+struct check_duplicate_loop
+{
+    typedef typename coordinate_type<Segment>::type coordinate_type;
+
+    static inline bool apply(Segment const& seg)
+    {
+        coordinate_type const diff =
+            ggl::get<1, Dimension>(seg) - ggl::get<0, Dimension>(seg);
+
+        if (! ggl::math::equals(diff, 0))
+        {
+            return false;
+        }
+
+        return check_duplicate_loop
+            <
+                Segment, Dimension + 1, DimensionCount
+            >::apply(seg);
+    }
+};
+
+template <typename Segment, std::size_t DimensionCount>
+struct check_duplicate_loop<Segment, DimensionCount, DimensionCount>
+{
+    static inline bool apply(Segment const&)
+    {
+        return true;
+    }
+};
+
+template <typename T, std::size_t Dimension, std::size_t DimensionCount>
+struct assign_loop
+{
+    static inline void apply(T dims[DimensionCount], int const value)
+    {
+        dims[Dimension] = value;
+        assign_loop<T, Dimension + 1, DimensionCount>::apply(dims, value);
+    }
+};
+
+template <typename T, std::size_t DimensionCount>
+struct assign_loop<T, DimensionCount, DimensionCount>
+{
+    static inline void apply(T dims[DimensionCount], int const)
+    {
+        boost::ignore_unused_variable_warning(dims);
+    }
+};
+
+
+template
+<
+    typename Range,
+    typename Point,
+    typename Sections,
+    std::size_t DimensionCount,
+    std::size_t MaxCount
+>
+struct sectionalize_range
+{
+    static inline void apply(Range const& range, Sections& sections,
+                int ring_index = -1, int multi_index = -1)
+    {
+        typedef segment<const Point> segment_type;
+
+        std::size_t const n = boost::size(range);
+        if (n == 0)
+        {
+            // Zero points, no section
+            return;
+        }
+
+        if (n == 1)
+        {
+            // Line with one point ==> no sections
+            return;
+        }
+
+        int i = 0;
+        int ndi = 0; // non duplicate index
+
+        typedef typename boost::range_value<Sections>::type sections_range_type;
+        sections_range_type section;
+
+        typedef typename boost::range_const_iterator<Range>::type iterator_type;
+        iterator_type it = boost::begin(range);
+
+        for(iterator_type previous = it++;
+            it != boost::end(range);
+            previous = it++, i++)
+        {
+            segment_type s(*previous, *it);
+
+            int direction_classes[DimensionCount] = {0};
+            get_direction_loop
+                <
+                    segment_type, 0, DimensionCount
+                >::apply(s, direction_classes);
+
+            // if "dir" == 0 for all point-dimensions, it is duplicate.
+            // Those sections might be omitted, if wished, lateron
+            bool check_duplicate = true; //?
+            bool duplicate = false;
+
+            if (check_duplicate && direction_classes[0] == 0)
+            {
+                // Recheck because all dimensions should be checked,
+                // not only first one,
+                // Note that DimensionCount might be < dimension<P>::value
+                if (check_duplicate_loop
+                    <
+                        segment_type, 0, ggl::dimension<Point>::type::value
+                    >::apply(s)
+                    )
+                {
+                    duplicate = true;
+
+                    // Change direction-info to force new section
+                    // Note that wo consecutive duplicate segments will generate
+                    // only one duplicate-section.
+                    // Actual value is not important as long as it is not -1,0,1
+                    assign_loop
+                    <
+                        int, 0, DimensionCount
+                    >::apply(direction_classes, -99);
+                }
+            }
+
+            if (section.count > 0
+                && (!compare_loop
+                        <
+                            int, 0, DimensionCount
+                        >::apply(direction_classes, section.directions)
+                    || section.count > MaxCount
+                    )
+                )
+            {
+                sections.push_back(section);
+                section = sections_range_type();
+            }
+
+            if (section.count == 0)
+            {
+                section.begin_index = i;
+                section.ring_index = ring_index;
+                section.multi_index = multi_index;
+                section.duplicate = duplicate;
+                section.non_duplicate_index = ndi;
+                section.range_count = boost::size(range);
+
+                copy_loop
+                    <
+                        int, 0, DimensionCount
+                    >::apply(direction_classes, section.directions);
+                ggl::combine(section.bounding_box, *previous);
+            }
+
+            ggl::combine(section.bounding_box, *it);
+            section.end_index = i + 1;
+            section.count++;
+            if (! duplicate)
+            {
+                ndi++;
+            }
+        }
+
+        if (section.count > 0)
+        {
+            sections.push_back(section);
+        }
+    }
+};
+
+template
+<
+    typename Polygon,
+    typename Sections,
+    std::size_t DimensionCount,
+    std::size_t MaxCount
+>
+struct sectionalize_polygon
+{
+    static inline void apply(Polygon const& poly, Sections& sections,
+                int multi_index = -1)
+    {
+        typedef typename point_type<Polygon>::type point_type;
+        typedef typename ring_type<Polygon>::type ring_type;
+        typedef sectionalize_range
+            <
+                ring_type, point_type, Sections, DimensionCount, MaxCount
+            > sectionalizer_type;
+
+        typedef typename boost::range_const_iterator
+            <
+            typename interior_type<Polygon>::type
+            >::type iterator_type;
+
+        sectionalizer_type::apply(exterior_ring(poly), sections, -1, multi_index);
+
+        int i = 0;
+        for (iterator_type it = boost::begin(interior_rings(poly));
+             it != boost::end(interior_rings(poly));
+             ++it, ++i)
+        {
+            sectionalizer_type::apply(*it, sections, i, multi_index);
+        }
+    }
+};
+
+template
+<
+    typename Box,
+    typename Sections,
+    std::size_t DimensionCount,
+    std::size_t MaxCount
+>
+struct sectionalize_box
+{
+    static inline void apply(Box const& box, Sections& sections)
+    {
+        typedef typename point_type<Box>::type point_type;
+
+        assert_dimension<Box, 2>();
+
+        // Add all four sides of the 2D-box as separate section.
+        // Easiest is to convert it to a polygon.
+        // However, we don't have the polygon type
+        // (or polygon would be a helper-type).
+        // Therefore we mimic a linestring/std::vector of 5 points
+
+        point_type ll, lr, ul, ur;
+        assign_box_corners(box, ll, lr, ul, ur);
+
+        std::vector<point_type> points;
+        points.push_back(ll);
+        points.push_back(ul);
+        points.push_back(ur);
+        points.push_back(lr);
+        points.push_back(ll);
+
+        sectionalize_range
+            <
+                std::vector<point_type>,
+                point_type,
+                Sections,
+                DimensionCount,
+                MaxCount
+            >::apply(points, sections);
+    }
+};
+
+}} // namespace detail::sectionalize
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+    typename Tag,
+    typename Geometry,
+    typename Sections,
+    std::size_t DimensionCount,
+    std::size_t MaxCount
+>
+struct sectionalize
+{};
+
+template
+<
+    typename Box,
+    typename Sections,
+    std::size_t DimensionCount,
+    std::size_t MaxCount
+>
+struct sectionalize<box_tag, Box, Sections, DimensionCount, MaxCount>
+    : detail::sectionalize::sectionalize_box
+        <
+            Box,
+            Sections,
+            DimensionCount,
+            MaxCount
+        >
+{};
+
+template
+<
+    typename LineString, typename
+    Sections,
+    std::size_t DimensionCount,
+    std::size_t MaxCount
+>
+struct sectionalize
+    <
+        linestring_tag,
+        LineString,
+        Sections,
+        DimensionCount,
+        MaxCount
+    >
+    : detail::sectionalize::sectionalize_range
+        <
+            LineString,
+            typename point_type<LineString>::type,
+            Sections,
+            DimensionCount,
+            MaxCount
+        >
+{};
+
+template
+<
+    typename Range,
+    typename Sections,
+    std::size_t DimensionCount,
+    std::size_t MaxCount
+>
+struct sectionalize<ring_tag, Range, Sections, DimensionCount, MaxCount>
+    : detail::sectionalize::sectionalize_range
+        <
+            Range,
+            typename point_type<Range>::type,
+            Sections,
+            DimensionCount,
+            MaxCount
+        >
+{};
+
+template
+<
+    typename Polygon,
+    typename Sections,
+    std::size_t DimensionCount,
+    std::size_t MaxCount
+>
+struct sectionalize<polygon_tag, Polygon, Sections, DimensionCount, MaxCount>
+    : detail::sectionalize::sectionalize_polygon
+        <
+            Polygon, Sections, DimensionCount, MaxCount
+        >
+{};
+
+} // namespace dispatch
+#endif
+
+
+/*!
+    \brief Split a geometry into monotonic sections
+    \ingroup sectionalize
+    \tparam Geometry type of geometry to check
+    \tparam Sections type of sections to create
+    \param geometry geometry to create sections from
+    \param sections structure with sections
+
+ */
+template<typename Geometry, typename Sections>
+inline void sectionalize(Geometry const& geometry, Sections& sections)
+{
+    concept::check<const Geometry>();
+
+    // A maximum of 10 segments per section seems to give the fastest results
+    static const std::size_t max_segments_per_section = 10;
+    typedef dispatch::sectionalize
+        <
+            typename tag<Geometry>::type,
+            Geometry,
+            Sections,
+            Sections::value,
+            max_segments_per_section
+        > sectionalizer_type;
+
+    sections.clear();
+    sectionalizer_type::apply(geometry, sections);
+}
+
+
+
+
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_SECTIONALIZE_HPP
Added: sandbox/ggl/formal_review/boost/ggl/algorithms/simplify.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/algorithms/simplify.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,409 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_SIMPLIFY_HPP
+#define GGL_ALGORITHMS_SIMPLIFY_HPP
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+
+#include <ggl/core/cs.hpp>
+#include <ggl/core/ring_type.hpp>
+#include <ggl/core/exterior_ring.hpp>
+#include <ggl/core/interior_rings.hpp>
+
+#include <ggl/geometries/concepts/check.hpp>
+
+#include <ggl/strategies/agnostic/simplify_douglas_peucker.hpp>
+#include <ggl/strategies/concepts/simplify_concept.hpp>
+
+#include <ggl/algorithms/clear.hpp>
+
+
+
+/*!
+\defgroup simplify simplify: remove points from a geometry, keeping shape (simplification or generalization)
+\par Source description:
+- Wikipedia: given a 'curve' composed of line segments to find a curve
+    not too dissimilar but that has fewer points
+
+\see http://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm
+
+\par Performance
+- Performance is measured on simplification of a collection of rings,
+    such that 10% of the points is kept.
+- 2776 counties of US are simplified in 0.7 seconds
+(http://trac.osgeo.org/ggl/wiki/Performance#Simplify1)
+
+\par Geometries
+- \b linestring:
+\image html svg_simplify_road.png
+This US Road originally contained 34 points, the simplified version contains 7 points
+
+- \b polygon:
+\image html svg_simplify_country.png
+This country (Belgium) originally contained 55 points, the simplified version contains 24 points
+
+\note simplifying a valid simple polygon (which never intersects itself)
+    might result in an invalid polygon, where the simplified rings intersect
+    themselves or one of the other outer or inner rings.
+Efficient simplification of a ring/polygon is still an "Open Problem"
+(http://maven.smith.edu/~orourke/TOPP/P24.html#Problem.24)
+
+- \b multi_linestring
+- \b multi_polygon
+
+
+*/
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace simplify {
+
+template<typename Range, typename Strategy>
+struct simplify_range_inserter
+{
+    template <typename OutputIterator>
+    static inline void apply(Range const& range, OutputIterator out,
+                    double max_distance, Strategy const& strategy)
+    {
+        if (boost::size(range) <= 2 || max_distance < 0)
+        {
+            std::copy(boost::begin(range), boost::end(range), out);
+        }
+        else
+        {
+            strategy.apply(range, out, max_distance);
+        }
+    }
+};
+
+
+template<typename Range, typename Strategy>
+struct simplify_copy
+{
+    static inline void apply(Range const& range, Range& out,
+                    double max_distance, Strategy const& strategy)
+    {
+        std::copy
+            (
+                boost::begin(range), boost::end(range), std::back_inserter(out)
+            );
+    }
+};
+
+
+template<typename Range, typename Strategy, std::size_t Minimum>
+struct simplify_range
+{
+    static inline void apply(Range const& range, Range& out,
+                    double max_distance, Strategy const& strategy)
+    {
+        // Call do_container for a linestring / ring
+
+        /* For a RING:
+            The first/last point (the closing point of the ring) should maybe
+            be excluded because it lies on a line with second/one but last.
+            Here it is never excluded.
+
+            Note also that, especially if max_distance is too large,
+            the output ring might be self intersecting while the input ring is
+            not, although chances are low in normal polygons
+
+            Finally the inputring might have 4 points (=correct),
+                the output < 4(=wrong)
+        */
+
+        if (boost::size(range) <= int(Minimum) || max_distance < 0.0)
+        {
+            simplify_copy<Range, Strategy>::apply
+                (
+                    range, out, max_distance, strategy
+                );
+        }
+        else
+        {
+            simplify_range_inserter<Range, Strategy>::apply
+                (
+                    range, std::back_inserter(out), max_distance, strategy
+                );
+        }
+    }
+};
+
+template<typename Polygon, typename Strategy>
+struct simplify_polygon
+{
+    static inline void apply(Polygon const& poly_in, Polygon& poly_out,
+                    double max_distance, Strategy const& strategy)
+    {
+        typedef typename ring_type<Polygon>::type ring_type;
+
+        typedef typename boost::range_iterator
+            <typename interior_type<Polygon>::type>::type iterator_type;
+        typedef typename boost::range_const_iterator
+            <typename interior_type<Polygon>::type>::type const_iterator_type;
+
+        // Note that if there are inner rings, and distance is too large,
+        // they might intersect with the outer ring in the output,
+        // while it didn't in the input.
+        simplify_range<ring_type, Strategy, 4>::apply(exterior_ring(poly_in),
+                        exterior_ring(poly_out),
+                        max_distance, strategy);
+
+        // Note: here a resizeable container is assumed.
+        // Maybe we should make this part of the concept.
+        interior_rings(poly_out).resize(num_interior_rings(poly_in));
+
+        iterator_type it_out = boost::begin(interior_rings(poly_out));
+
+        for (const_iterator_type it_in = boost::begin(interior_rings(poly_in));
+            it_in != boost::end(interior_rings(poly_in));
+            ++it_in, ++it_out)
+        {
+            simplify_range<ring_type, Strategy, 4>::apply(*it_in,
+                        *it_out, max_distance, strategy);
+        }
+    }
+};
+
+
+}} // namespace detail::simplify
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Tag, typename Geometry, typename Strategy>
+struct simplify
+{
+};
+
+template <typename Point, typename Strategy>
+struct simplify<point_tag, Point, Strategy>
+{
+    static inline void apply(Point const& point, Point& out,
+                    double max_distance, Strategy const& strategy)
+    {
+        copy_coordinates(point, out);
+    }
+};
+
+
+template <typename Linestring, typename Strategy>
+struct simplify<linestring_tag, Linestring, Strategy>
+    : detail::simplify::simplify_range
+            <
+                Linestring,
+                Strategy,
+                2
+            >
+{};
+
+template <typename Ring, typename Strategy>
+struct simplify<ring_tag, Ring, Strategy>
+    : detail::simplify::simplify_range
+            <
+                Ring,
+                Strategy,
+                4
+            >
+{};
+
+template <typename Polygon, typename Strategy>
+struct simplify<polygon_tag, Polygon, Strategy>
+    : detail::simplify::simplify_polygon
+            <
+                Polygon,
+                Strategy
+            >
+{};
+
+
+template <typename Tag, typename Geometry, typename Strategy>
+struct simplify_inserter
+{
+};
+
+
+template <typename Linestring, typename Strategy>
+struct simplify_inserter<linestring_tag, Linestring, Strategy>
+    : detail::simplify::simplify_range_inserter
+            <
+                Linestring,
+                Strategy
+            >
+{};
+
+template <typename Ring, typename Strategy>
+struct simplify_inserter<ring_tag, Ring, Strategy>
+    : detail::simplify::simplify_range_inserter
+            <
+                Ring,
+                Strategy
+            >
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+    \brief Simplify a geometry using a specified strategy
+    \ingroup simplify
+    \param geometry input geometry, to be simplified
+    \param out output geometry, simplified version of the input geometry
+    \param max_distance distance (in units of input coordinates) of a vertex
+        to other segments to be removed
+    \param strategy simplify strategy to be used for simplification, might
+        include point-distance strategy
+ */
+template<typename Geometry, typename Strategy>
+inline void simplify(Geometry const& geometry, Geometry& out,
+                     double max_distance, Strategy const& strategy)
+{
+    concept::check<Geometry>();
+
+    BOOST_CONCEPT_ASSERT( (ggl::concept::SimplifyStrategy<Strategy>) );
+
+    ggl::clear(out);
+
+    dispatch::simplify
+        <
+            typename tag<Geometry>::type,
+            Geometry,
+            Strategy
+        >::apply(geometry, out, max_distance, strategy);
+}
+
+
+
+
+/*!
+    \brief Simplify a geometry
+    \ingroup simplify
+    \note This version of simplify simplifies a geometry using the default
+        strategy (Douglas Peucker),
+    \param geometry input geometry, to be simplified
+    \param out output geometry, simplified version of the input geometry
+    \param max_distance distance (in units of input coordinates) of a vertex
+        to other segments to be removed
+    \par Example:
+    The simplify algorithm can be used as following:
+    \dontinclude doxygen_1.cpp
+    \skip example_simplify_linestring1
+    \line {
+    \until }
+ */
+template<typename Geometry>
+inline void simplify(Geometry const& geometry, Geometry& out,
+                     double max_distance)
+{
+    concept::check<Geometry>();
+
+    typedef typename point_type<Geometry>::type point_type;
+    typedef typename cs_tag<point_type>::type cs_tag;
+    typedef typename strategy_distance_segment
+        <
+            cs_tag,
+            cs_tag,
+            point_type,
+            point_type
+        >::type ds_strategy_type;
+
+    typedef strategy::simplify::douglas_peucker
+        <
+            point_type, ds_strategy_type
+        > strategy_type;
+
+    simplify(geometry, out, max_distance, strategy_type());
+}
+
+
+/*!
+    \brief Simplify a geometry, using an output iterator
+        and a specified strategy
+    \ingroup simplify
+    \param geometry input geometry, to be simplified
+    \param out output iterator, outputs all simplified points
+    \param max_distance distance (in units of input coordinates) of a vertex
+        to other segments to be removed
+    \param strategy simplify strategy to be used for simplification,
+        might include point-distance strategy
+    \par Example:
+    simplify_inserter with strategy is used as following:
+    \dontinclude doxygen_1.cpp
+    \skip example_simplify_linestring2
+    \line {
+    \until }
+ */
+template<typename Geometry, typename OutputIterator, typename Strategy>
+inline void simplify_inserter(Geometry const& geometry, OutputIterator out,
+                              double max_distance, Strategy const& strategy)
+{
+    concept::check<const Geometry>();
+    BOOST_CONCEPT_ASSERT( (ggl::concept::SimplifyStrategy<Strategy>) );
+
+    dispatch::simplify_inserter
+        <
+            typename tag<Geometry>::type,
+            Geometry,
+            Strategy
+        >::apply(geometry, out, max_distance, strategy);
+}
+
+/*!
+    \brief Simplify a geometry, using an output iterator
+    \ingroup simplify
+    \param geometry input geometry, to be simplified
+    \param out output iterator, outputs all simplified points
+    \param max_distance distance (in units of input coordinates) of a vertex
+        to other segments to be removed
+ */
+template<typename Geometry, typename OutputIterator>
+inline void simplify_inserter(Geometry const& geometry, OutputIterator out,
+                              double max_distance)
+{
+    typedef typename point_type<Geometry>::type point_type;
+
+    // Concept: output point type = point type of input geometry
+    concept::check<const Geometry>();
+    concept::check<point_type>();
+
+    typedef typename cs_tag<point_type>::type cs_tag;
+    typedef typename strategy_distance_segment
+        <
+            cs_tag,
+            cs_tag,
+            point_type,
+            point_type
+        >::type ds_strategy_type;
+
+    typedef strategy::simplify::douglas_peucker
+        <
+            point_type, ds_strategy_type
+        > strategy_type;
+
+    dispatch::simplify_inserter
+        <
+            typename tag<Geometry>::type,
+            Geometry,
+            strategy_type
+        >::apply(geometry, out, max_distance, strategy_type());
+}
+
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_SIMPLIFY_HPP
Added: sandbox/ggl/formal_review/boost/ggl/algorithms/transform.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/algorithms/transform.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,335 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_TRANSFORM_HPP
+#define GGL_ALGORITHMS_TRANSFORM_HPP
+
+#include <cmath>
+#include <iterator>
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/algorithms/clear.hpp>
+#include <ggl/algorithms/assign.hpp>
+
+#include <ggl/core/cs.hpp>
+#include <ggl/core/exterior_ring.hpp>
+#include <ggl/core/interior_rings.hpp>
+#include <ggl/core/ring_type.hpp>
+
+#include <ggl/geometries/concepts/check.hpp>
+
+#include <ggl/strategies/transform.hpp>
+
+
+/*!
+\defgroup transform transform: apply transformations on geometries
+\brief Transforms from one geometry to another geometry, optionally using a strategy
+\details The transform algorithm automatically transforms from one coordinate system to another coordinate system.
+If the coordinate system of both geometries are the same, the geometry is copied. All point(s of the geometry)
+are transformed.
+
+There is a version without a strategy, transforming automatically, and there is a version with a strategy.
+
+This function has a lot of appliances, for example
+- transform from spherical coordinates to cartesian coordinates, and back
+- transform from geographic coordinates to cartesian coordinates (projections) and back
+- transform from degree to radian, and back
+- transform from and to cartesian coordinates (mapping, translations, etc)
+
+The automatic transformations look to the coordinate system family, and dimensions, of the point type and by this
+apply the strategy (internally bounded by traits classes).
+
+\par Examples:
+The example below shows automatic transformations to go from one coordinate system to another one:
+\dontinclude doxygen_2.cpp
+\skip example_for_transform()
+\skipline XYZ
+\until endl;
+
+The next example takes another approach and transforms from Cartesian to Cartesian:
+\skipline XY
+\until endl;
+
+\note Not every possibility is yet worked out, e.g. polar coordinate system is ignored until now
+\note This "transform" is broader then geodetic datum transformations, those are currently not worked out
+
+*/
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace transform {
+
+template <typename Point1, typename Point2, typename Strategy>
+struct transform_point
+{
+    static inline bool apply(Point1 const& p1, Point2& p2,
+                Strategy const& strategy)
+    {
+        return strategy(p1, p2);
+    }
+};
+
+template <typename Box1, typename Box2, typename Strategy>
+struct transform_box
+{
+    static inline bool apply(Box1 const& b1, Box2& b2,
+                Strategy const& strategy)
+    {
+        typedef typename point_type<Box1>::type point_type1;
+        typedef typename point_type<Box2>::type point_type2;
+
+        point_type1 lower_left, upper_right;
+        detail::assign::assign_box_2d_corner<min_corner, min_corner>(
+                    b1, lower_left);
+        detail::assign::assign_box_2d_corner<max_corner, max_corner>(
+                    b1, upper_right);
+
+        point_type2 p1, p2;
+        if (strategy(lower_left, p1) && strategy(upper_right, p2))
+        {
+            // Create a valid box and therefore swap if necessary
+            typedef typename coordinate_type<point_type2>::type coordinate_type;
+            coordinate_type x1 = ggl::get<0>(p1)
+                    , y1  = ggl::get<1>(p1)
+                    , x2  = ggl::get<0>(p2)
+                    , y2  = ggl::get<1>(p2);
+
+            if (x1 > x2) { std::swap(x1, x2); }
+            if (y1 > y2) { std::swap(y1, y2); }
+
+            set<min_corner, 0>(b2, x1);
+            set<min_corner, 1>(b2, y1);
+            set<max_corner, 0>(b2, x2);
+            set<max_corner, 1>(b2, y2);
+
+            return true;
+        }
+        return false;
+    }
+};
+
+template
+<
+    typename PointOut,
+    typename OutputIterator,
+    typename Range,
+    typename Strategy
+>
+inline bool transform_range_out(Range const& range,
+    OutputIterator out, Strategy const& strategy)
+{
+    PointOut point_out;
+    for(typename boost::range_const_iterator<Range>::type
+        it = boost::begin(range);
+        it != boost::end(range);
+        ++it)
+    {
+        if (! transform_point
+                <
+                    typename point_type<Range>::type,
+                    PointOut,
+                    Strategy
+                >::apply(*it, point_out, strategy))
+        {
+            return false;
+        }
+        *out = point_out;
+        ++out;
+    }
+    return true;
+}
+
+template <typename Polygon1, typename Polygon2, typename Strategy>
+struct transform_polygon
+{
+    static inline bool apply(const Polygon1& poly1, Polygon2& poly2,
+                Strategy const& strategy)
+    {
+        typedef typename interior_type<Polygon1>::type interior1_type;
+        typedef typename interior_type<Polygon2>::type interior2_type;
+        typedef typename ring_type<Polygon1>::type ring1_type;
+        typedef typename ring_type<Polygon2>::type ring2_type;
+        typedef typename point_type<Polygon2>::type point2_type;
+
+        ggl::clear(poly2);
+
+        if (!transform_range_out<point2_type>(exterior_ring(poly1),
+                    std::back_inserter(exterior_ring(poly2)), strategy))
+        {
+            return false;
+        }
+
+        interior_rings(poly2).resize(num_interior_rings(poly1));
+
+        typedef typename boost::range_const_iterator
+            <
+                interior1_type
+            >::type iterator1_type;
+        typedef typename boost::range_iterator
+            <
+                interior2_type
+            >::type iterator2_type;
+
+        iterator1_type it1 = boost::begin(interior_rings(poly1));
+        iterator2_type it2 = boost::begin(interior_rings(poly2));
+        for ( ; it1 != boost::end(interior_rings(poly1));
+            ++it1, ++it2)
+        {
+            if (!transform_range_out<point2_type>(*it1,
+                std::back_inserter(*it2), strategy))
+            {
+                return false;
+            }
+        }
+
+        return true;
+    }
+};
+
+
+template <typename Point1, typename Point2>
+struct select_strategy
+{
+    typedef typename strategy_transform
+        <
+        typename cs_tag<Point1>::type,
+        typename cs_tag<Point2>::type,
+        typename coordinate_system<Point1>::type,
+        typename coordinate_system<Point2>::type,
+        dimension<Point1>::type::value,
+        dimension<Point2>::type::value,
+        typename point_type<Point1>::type,
+        typename point_type<Point2>::type
+        >::type type;
+};
+
+template <typename Range1, typename Range2, typename Strategy>
+struct transform_range
+{
+    static inline bool apply(Range1 const& range1,
+            Range2& range2, Strategy const& strategy)
+    {
+        typedef typename point_type<Range2>::type point_type;
+
+        ggl::clear(range2);
+        return transform_range_out<point_type>(range1,
+                std::back_inserter(range2), strategy);
+    }
+};
+
+}} // namespace detail::transform
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+    typename Tag1, typename Tag2,
+    typename Geometry1, typename Geometry2,
+    typename Strategy
+>
+struct transform {};
+
+template <typename Point1, typename Point2, typename Strategy>
+struct transform<point_tag, point_tag, Point1, Point2, Strategy>
+    : detail::transform::transform_point<Point1, Point2, Strategy>
+{
+};
+
+
+template <typename Linestring1, typename Linestring2, typename Strategy>
+struct transform
+    <
+        linestring_tag, linestring_tag,
+        Linestring1, Linestring2, Strategy
+    >
+    : detail::transform::transform_range<Linestring1, Linestring2, Strategy>
+{
+};
+
+template <typename Range1, typename Range2, typename Strategy>
+struct transform<ring_tag, ring_tag, Range1, Range2, Strategy>
+    : detail::transform::transform_range<Range1, Range2, Strategy>
+{
+};
+
+template <typename Polygon1, typename Polygon2, typename Strategy>
+struct transform<polygon_tag, polygon_tag, Polygon1, Polygon2, Strategy>
+    : detail::transform::transform_polygon<Polygon1, Polygon2, Strategy>
+{
+};
+
+template <typename Box1, typename Box2, typename Strategy>
+struct transform<box_tag, box_tag, Box1, Box2, Strategy>
+    : detail::transform::transform_box<Box1, Box2, Strategy>
+{
+};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+    \brief Transforms from one geometry to another geometry using a strategy
+    \ingroup transform
+    \tparam Geometry1 first geometry type
+    \tparam Geometry2 second geometry type
+    \tparam Strategy strategy
+    \param geometry1 first geometry
+    \param geometry2 second geometry
+    \param strategy the strategy to be used for transformation
+ */
+template <typename Geometry1, typename Geometry2, typename Strategy>
+inline bool transform(Geometry1 const& geometry1, Geometry2& geometry2,
+            Strategy const& strategy)
+{
+    concept::check<const Geometry1>();
+    concept::check<Geometry2>();
+
+    typedef dispatch::transform
+        <
+            typename tag<Geometry1>::type,
+            typename tag<Geometry2>::type,
+            Geometry1,
+            Geometry2,
+            Strategy
+        > transform_type;
+
+    return transform_type::apply(geometry1, geometry2, strategy);
+}
+
+/*!
+    \brief Transforms from one geometry to another geometry using a strategy
+    \ingroup transform
+    \tparam Geometry1 first geometry type
+    \tparam Geometry2 second geometry type
+    \param geometry1 first geometry
+    \param geometry2 second geometry
+    \return true if the transformation could be done
+ */
+template <typename Geometry1, typename Geometry2>
+inline bool transform(Geometry1 const& geometry1, Geometry2& geometry2)
+{
+    concept::check<const Geometry1>();
+    concept::check<Geometry2>();
+
+    typename detail::transform::select_strategy<Geometry1, Geometry2>::type strategy;
+    return transform(geometry1, geometry2, strategy);
+}
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_TRANSFORM_HPP
Added: sandbox/ggl/formal_review/boost/ggl/algorithms/union.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/algorithms/union.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,263 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_UNION_HPP
+#define GGL_ALGORITHMS_UNION_HPP
+
+
+#include <boost/mpl/if.hpp>
+
+#include <ggl/core/interior_rings.hpp>
+#include <ggl/core/reverse_dispatch.hpp>
+#include <ggl/geometries/concepts/check.hpp>
+#include <ggl/algorithms/overlay/assemble.hpp>
+#include <ggl/algorithms/overlay/sort_interior_rings.hpp>
+#include <ggl/algorithms/within.hpp>
+
+
+
+/*!
+\defgroup union union: calculate new geometry containing geometries A or B
+\details The union of two geometries A and B is the geometry containing
+    all points belong to either of A or B, but no other elements.
+\par Source description:
+- OGC: Returns a geometric object that represents the Point set union of
+    this geometric object with another Geometry.
+\see http://en.wikipedia.org/wiki/Union_(set_theory)
+\note A union of two rings can result in a polygon having a hole
+
+\par Geometries:
+- \b polygon + \b box -> \b polygon(s)
+\image html svg_union_polygon_box.png
+- \b ring + \b box -> \b polygon(s)
+\image html svg_union_ring_box.png
+- \b ring + \b ring -> \b polygon(s)
+\image html svg_union_ring_ring.png
+- \b polygon + \b ring -> \b polygon(s)
+\image html svg_union_polygon_ring.png
+- combinations above -> \b ring(s).
+    <i>If the output is an ouput iterator of rings, holes are omitted</i>
+
+*/
+
+namespace ggl
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace overlay {
+
+
+// Specializations for "take_one" for union
+// "one" should be the outer one, containing the inner one
+
+// for ring and box
+template
+<
+    typename Tag1, typename Geometry1,
+    typename Tag2, typename Geometry2,
+    typename GeometryOut
+>
+struct take_if_1_is_in_2<Tag1, Geometry1, Tag2, Geometry2, GeometryOut, 1>
+{
+    static inline void apply(Geometry1 const& geometry1,
+                Geometry2 const& geometry2,
+                GeometryOut& out
+                )
+    {
+        ggl::convert(geometry2, out);
+    }
+};
+
+
+// spcialize more for polygons
+template
+<
+    typename Tag1, typename Geometry1,
+    typename Geometry2,
+    typename GeometryOut
+>
+struct take_if_1_is_in_2<Tag1, Geometry1, polygon_tag, Geometry2, GeometryOut, 1>
+{
+    static inline void apply(Geometry1 const& geometry1,
+                Geometry2 const& geometry2,
+                GeometryOut& out
+                )
+    {
+        ggl::convert(exterior_ring(geometry2), out);
+    }
+};
+
+
+template
+<
+    typename Geometry, typename GeometryOut, typename Container
+>
+struct add_holes<polygon_tag, Geometry, GeometryOut, Container, 1>
+{
+    static inline void apply(Geometry const& geometry,
+                GeometryOut& out,
+                Container const& holes
+                )
+    {
+        std::vector<sortable> v;
+        sort_interior_rings(holes, v, -1);
+
+        // For a union, if a ring is containing an inner ring, don't take the outer
+        // but leave to the inners.
+        // If the inner is lying in geometry2, don't add it
+
+        std::size_t const n = boost::size(v);
+
+        for (std::size_t i = 0; i < n; i++)
+        {
+            // So, only if no inners:
+            if (boost::size(v[i].index_of_holes) == 0)
+            {
+                bool add = v[i].index_of_parent >= 0;
+                if (! add)
+                {
+                    typename ggl::point_type<GeometryOut>::type point;
+                    ggl::point_on_border(holes[v[i].index], point);
+                    add = ! ggl::within(point, geometry);
+                }
+                if (add)
+                {
+                    typename ring_type<GeometryOut>::type hole;
+                    ggl::convert(holes[v[i].index], hole);
+                    ggl::interior_rings(out).push_back(hole);
+                }
+            }
+        }
+    }
+};
+
+
+
+// "none or both" should be both
+template
+<
+    typename Geometry1, typename Geometry2,
+    typename OutputIterator, typename GeometryOut
+>
+struct take_none_or_both<Geometry1, Geometry2, OutputIterator, GeometryOut, 1>
+{
+    static inline void apply(Geometry1 const& geometry1,
+                Geometry2 const& geometry2,
+                OutputIterator out
+                )
+    {
+        convert_and_output<GeometryOut>(geometry1, out);
+        convert_and_output<GeometryOut>(geometry2, out);
+    }
+};
+
+
+}} // namespace detail::overlay
+#endif // DOXYGEN_NO_DETAIL
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+    typename Tag1, typename Tag2, typename Tag3,
+    typename G1, typename G2,
+    typename OutputIterator,
+    typename GeometryOut
+>
+struct union_inserter
+    : detail::overlay::overlay_and_assemble
+        <G1, G2, OutputIterator, GeometryOut, 1>
+{
+};
+
+
+template
+<
+    typename GeometryTag1, typename GeometryTag2, typename GeometryTag3,
+    typename Geometry1, typename Geometry2,
+    typename OutputIterator, typename GeometryOut
+>
+struct union_inserter_reversed
+{
+    static inline OutputIterator apply(Geometry1 const& g1,
+            Geometry2 const& g2, OutputIterator out)
+    {
+        return union_inserter
+            <
+                GeometryTag2, GeometryTag1, GeometryTag3,
+                Geometry2, Geometry1,
+                OutputIterator, GeometryOut
+            >::apply(g2, g1, out);
+    }
+};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+    \brief Combines two geometries which each other
+    \ingroup union
+    \tparam GeometryOut output geometry type, must be specified
+    \tparam Geometry1 first geometry type
+    \tparam Geometry2 second geometry type
+    \tparam OutputIterator output iterator
+    \param geometry1 first geometry
+    \param geometry2 second geometry
+    \param out the output iterator, outputting polygons
+    \return the output iterator
+*/
+template
+<
+    typename GeometryOut,
+    typename Geometry1,
+    typename Geometry2,
+    typename OutputIterator
+>
+inline OutputIterator union_inserter(Geometry1 const& geometry1,
+            Geometry2 const& geometry2,
+            OutputIterator out)
+{
+    concept::check<const Geometry1>();
+    concept::check<const Geometry2>();
+
+    return boost::mpl::if_c
+        <
+            reverse_dispatch<Geometry1, Geometry2>::type::value,
+            dispatch::union_inserter_reversed
+            <
+                typename tag<Geometry1>::type,
+                typename tag<Geometry2>::type,
+                typename tag<GeometryOut>::type,
+                Geometry1,
+                Geometry2,
+                OutputIterator, GeometryOut
+            >,
+            dispatch::union_inserter
+            <
+                typename tag<Geometry1>::type,
+                typename tag<Geometry2>::type,
+                typename tag<GeometryOut>::type,
+                Geometry1,
+                Geometry2,
+                OutputIterator, GeometryOut
+            >
+        >::type::apply(geometry1, geometry2, out);
+}
+
+
+} // ggl
+
+
+#endif //GGL_ALGORITHMS_UNION_HPP
Added: sandbox/ggl/formal_review/boost/ggl/algorithms/within.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/algorithms/within.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,373 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ALGORITHMS_WITHIN_HPP
+#define GGL_ALGORITHMS_WITHIN_HPP
+
+/*!
+\defgroup within within: detect if a geometry is inside another geometry, a.o. point-in-polygon
+
+\par Source descriptions:
+- OGC: Returns 1 (TRUE) if this geometric object is "spatially within"
+        another Geometry.
+
+\par Performance
+- 2776 within determinations using bounding box and polygon are done
+    in 0.05 seconds (http://trac.osgeo.org/ggl/wiki/Performance#Within1)
+- note that using another strategy the performance can be increased:
+  - winding            : 0.093 s
+  - franklin           : 0.062 s
+  - Crossings-multiply : 0.047 s
+- but note also that the last two do not detect point-on-border cases
+
+\par Geometries:
+- \b point + \b polygon: The well-known point-in-polygon, returning true if
+    a point falls within a polygon (and not
+within one of its holes) \image html within_polygon.png
+- \b point + \b ring: returns true if point is completely within
+    a ring \image html within_ring.png
+- \b point + \b box
+- \b box + \b box
+
+\par Example:
+The within algorithm is used as following:
+\dontinclude doxygen_1.cpp
+\skip example_within
+\line {
+\until }
+
+*/
+
+
+#include <cstddef>
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/algorithms/distance.hpp>
+#include <ggl/algorithms/make.hpp>
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/exterior_ring.hpp>
+#include <ggl/core/interior_rings.hpp>
+#include <ggl/core/cs.hpp>
+
+#include <ggl/geometries/concepts/check.hpp>
+
+#include <ggl/strategies/point_in_poly.hpp>
+#include <ggl/strategies/concepts/within_concept.hpp>
+
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace within {
+
+
+/*!
+    \brief Implementation for boxes
+    \ingroup boolean_relations
+    \note Should have strategy for e.g. Wrangel
+ */
+template
+<
+    typename Point,
+    typename Box,
+    typename Strategy,
+    std::size_t Dimension,
+    std::size_t DimensionCount
+>
+struct point_in_box
+{
+    static inline bool apply(Point const& p, Box const& b, Strategy const& s)
+    {
+        assert_dimension_equal<Point, Box>();
+
+        if (get<Dimension>(p) <= get<min_corner, Dimension>(b)
+            || get<Dimension>(p) >= get<max_corner, Dimension>(b))
+        {
+            return false;
+        }
+
+        return point_in_box
+            <
+                Point,
+                Box,
+                Strategy,
+                Dimension + 1,
+                DimensionCount
+            >::apply(p, b, s);
+    }
+};
+
+template
+<
+    typename Point,
+    typename Box,
+    typename Strategy,
+    std::size_t DimensionCount
+>
+struct point_in_box<Point, Box, Strategy, DimensionCount, DimensionCount>
+{
+    static inline bool apply(Point const& p, Box const& b, Strategy const& s)
+    {
+        return true;
+    }
+};
+
+
+template
+<
+    typename Box1,
+    typename Box2,
+    typename Strategy,
+    std::size_t Dimension,
+    std::size_t DimensionCount
+>
+struct box_in_box
+{
+    static inline bool apply(Box1 const& b1, Box2 const& b2, Strategy const& s)
+    {
+        assert_dimension_equal<Box1, Box2>();
+
+        if (get<min_corner, Dimension>(b1) <= get<min_corner, Dimension>(b2)
+            || get<max_corner, Dimension>(b1) >= get<max_corner, Dimension>(b2))
+        {
+            return false;
+        }
+
+        return box_in_box
+            <
+                Box1,
+                Box2,
+                Strategy,
+                Dimension + 1,
+                DimensionCount
+            >::apply(b1, b2, s);
+    }
+};
+
+template
+<
+    typename Box1,
+    typename Box2,
+    typename Strategy,
+    std::size_t DimensionCount
+>
+struct box_in_box<Box1, Box2, Strategy, DimensionCount, DimensionCount>
+{
+    static inline bool apply(Box1 const& , Box2 const& , Strategy const&)
+    {
+        return true;
+    }
+};
+
+
+template<typename Point, typename Ring, typename Strategy>
+struct point_in_ring
+{
+    BOOST_CONCEPT_ASSERT( (ggl::concept::WithinStrategy<Strategy>) );
+
+    static inline bool apply(Point const& point, Ring const& ring,
+            Strategy const& strategy)
+    {
+        if (boost::size(ring) < 4)
+        {
+            return false;
+        }
+
+        typedef typename boost::range_const_iterator<Ring>::type iterator_type;
+
+        typename Strategy::state_type state;
+
+        iterator_type it = boost::begin(ring);
+        for (iterator_type previous = it++;
+            it != boost::end(ring);
+            previous = it++)
+        {
+            if (! Strategy::apply(point, *previous, *it, state))
+            {
+                return false;
+            }
+        }
+        return Strategy::result(state);
+    }
+};
+
+// Polygon: in exterior ring, and if so, not within interior ring(s)
+template<typename Point, typename Polygon, typename Strategy>
+struct point_in_polygon
+{
+    BOOST_CONCEPT_ASSERT( (ggl::concept::WithinStrategy<Strategy>) );
+
+    static inline bool apply(Point const& point, Polygon const& poly,
+            Strategy const& strategy)
+    {
+
+        typedef point_in_ring
+            <
+                Point,
+                typename ring_type<Polygon>::type,
+                Strategy
+            > per_ring;
+
+        if (per_ring::apply(point, exterior_ring(poly), strategy))
+        {
+
+            for (typename boost::range_const_iterator
+                    <
+                        typename interior_type<Polygon>::type
+                    >::type it = boost::begin(interior_rings(poly));
+                 it != boost::end(interior_rings(poly));
+                 ++it)
+            {
+                if (per_ring::apply(point, *it, strategy))
+                {
+                    return false;
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+};
+
+}} // namespace detail::within
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+    typename Tag1,
+    typename Tag2,
+    typename Geometry1,
+    typename Geometry2,
+    typename Strategy
+>
+struct within
+{};
+
+
+template <typename Point, typename Box, typename Strategy>
+struct within<point_tag, box_tag, Point, Box, Strategy>
+    : detail::within::point_in_box
+            <
+                Point,
+                Box,
+                Strategy,
+                0,
+                dimension<Point>::type::value
+            >
+{};
+
+template <typename Box1, typename Box2, typename Strategy>
+struct within<box_tag, box_tag, Box1, Box2, Strategy>
+    : detail::within::box_in_box
+            <
+                Box1,
+                Box2,
+                Strategy,
+                0,
+                dimension<Box1>::type::value
+            >
+{};
+
+
+
+template <typename Point, typename Ring, typename Strategy>
+struct within<point_tag, ring_tag, Point, Ring, Strategy>
+    : detail::within::point_in_ring
+        <Point, Ring, Strategy>
+{};
+
+template <typename Point, typename Polygon, typename Strategy>
+struct within<point_tag, polygon_tag, Point, Polygon, Strategy>
+    : detail::within::point_in_polygon
+        <Point, Polygon, Strategy>
+{};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+    \brief Within, examine if a geometry is within another geometry
+    \ingroup within
+    \param geometry1 geometry which might be within the second geometry
+    \param geometry2 geometry which might contain the first geometry
+    \return true if geometry1 is completely contained within geometry2,
+        else false
+    \note The default strategy is used for within detection
+
+ */
+template<typename Geometry1, typename Geometry2>
+inline bool within(Geometry1 const& geometry1, Geometry2 const& geometry2)
+{
+    concept::check<const Geometry1>();
+    concept::check<const Geometry2>();
+
+    typedef typename point_type<Geometry1>::type point_type1;
+    typedef typename point_type<Geometry2>::type point_type2;
+
+    typedef typename strategy_within
+        <
+            typename cs_tag<point_type1>::type,
+            typename cs_tag<point_type2>::type,
+            point_type1,
+            point_type2
+        >::type strategy_type;
+
+    return dispatch::within
+        <
+            typename tag<Geometry1>::type,
+            typename tag<Geometry2>::type,
+            Geometry1,
+            Geometry2,
+            strategy_type
+        >::apply(geometry1, geometry2, strategy_type());
+}
+
+/*!
+    \brief Within, examine if a geometry is within another geometry,
+        using a specified strategy
+    \ingroup within
+    \param geometry1 geometry which might be within the second geometry
+    \param geometry2 geometry which might contain the first geometry
+    \param strategy strategy to be used
+    \return true if geometry1 is completely contained within geometry2,
+        else false
+ */
+template<typename Geometry1, typename Geometry2, typename Strategy>
+inline bool within(Geometry1 const& geometry1, Geometry2 const& geometry2,
+        Strategy const& strategy)
+{
+    // Always assume a point-in-polygon strategy here.
+    // Because for point-in-box, it makes no sense to specify one.
+    BOOST_CONCEPT_ASSERT( (ggl::concept::WithinStrategy<Strategy>) );
+
+    concept::check<const Geometry1>();
+    concept::check<const Geometry2>();
+
+    return dispatch::within
+        <
+            typename tag<Geometry1>::type,
+            typename tag<Geometry2>::type,
+            Geometry1,
+            Geometry2,
+            Strategy
+        >::apply(geometry1, geometry2, strategy);
+}
+
+} // namespace ggl
+
+#endif // GGL_ALGORITHMS_WITHIN_HPP
Added: sandbox/ggl/formal_review/boost/ggl/arithmetic/arithmetic.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/arithmetic/arithmetic.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,209 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ARITHMETIC_ARITHMETIC_HPP
+#define GGL_ARITHMETIC_ARITHMETIC_HPP
+
+#include <functional>
+
+#include <boost/call_traits.hpp>
+#include <boost/concept/requires.hpp>
+
+#include <ggl/core/coordinate_type.hpp>
+#include <ggl/geometries/concepts/point_concept.hpp>
+#include <ggl/util/for_each_coordinate.hpp>
+
+/*!
+\defgroup arithmetic arithmetic: arithmetic operations on points
+*/
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+template <typename P>
+struct param
+{
+    typedef typename boost::call_traits
+        <
+            typename coordinate_type<P>::type
+        >::param_type type;
+};
+
+template <typename C, template <typename> class Function>
+struct value_operation
+{
+    C m_value;
+
+    inline value_operation(C const &value)
+        : m_value(value)
+    {}
+
+    template <typename P, int I>
+    inline void apply(P& point) const
+    {
+        set<I>(point, Function<C>()(get<I>(point), m_value));
+    }
+};
+
+template <typename PointSrc, template <typename> class Function>
+struct point_operation
+{
+    typedef typename coordinate_type<PointSrc>::type coordinate_type;
+    PointSrc const& m_source_point;
+
+    inline point_operation(PointSrc const& point)
+        : m_source_point(point)
+    {}
+
+    template <typename PointDst, int I>
+    inline void apply(PointDst& dest_point) const
+    {
+        set<I>(dest_point,
+            Function<coordinate_type>()(get<I>(dest_point), get<I>(m_source_point)));
+    }
+};
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+/*!
+    \brief Adds a value to each coordinate of a point
+    \ingroup arithmetic
+    \details
+    \param p point
+    \param value value to add
+ */
+template <typename Point>
+inline void add_value(Point& p, typename detail::param<Point>::type value)
+{
+    BOOST_CONCEPT_ASSERT( (concept::Point<Point>) );
+
+    for_each_coordinate(p, detail::value_operation<typename coordinate_type<Point>::type, std::plus>(value));
+}
+
+/*!
+    \brief Adds a point to another
+    \ingroup arithmetic
+    \details The coordinates of the second point will be added to those of the first point.
+             The second point is not modified.
+    \param p1 first point
+    \param p2 second point
+ */
+template <typename Point1, typename Point2>
+inline void add_point(Point1& p1, Point2 const& p2)
+{
+    BOOST_CONCEPT_ASSERT( (concept::Point<Point2>) );
+    BOOST_CONCEPT_ASSERT( (concept::ConstPoint<Point2>) );
+
+    for_each_coordinate(p1, detail::point_operation<Point2, std::plus>(p2));
+}
+
+/*!
+    \brief Subtracts a value to each coordinate of a point
+    \ingroup arithmetic
+    \details
+    \param p point
+    \param value value to subtract
+ */
+template <typename Point>
+inline void subtract_value(Point& p, typename detail::param<Point>::type value)
+{
+    BOOST_CONCEPT_ASSERT( (concept::Point<Point>) );
+
+    for_each_coordinate(p, detail::value_operation<typename coordinate_type<Point>::type, std::minus>(value));
+}
+
+/*!
+    \brief Subtracts a point to another
+    \ingroup arithmetic
+    \details The coordinates of the second point will be subtracted to those of the first point.
+             The second point is not modified.
+    \param p1 first point
+    \param p2 second point
+ */
+template <typename Point1, typename Point2>
+inline void subtract_point(Point1& p1, Point2 const& p2)
+{
+    BOOST_CONCEPT_ASSERT( (concept::Point<Point2>) );
+    BOOST_CONCEPT_ASSERT( (concept::ConstPoint<Point2>) );
+
+    for_each_coordinate(p1, detail::point_operation<Point2, std::minus>(p2));
+}
+
+/*!
+    \brief Multiplies each coordinate of a point by a value
+    \ingroup arithmetic
+    \details
+    \param p point
+    \param value value to multiply by
+ */
+template <typename Point>
+inline void multiply_value(Point& p, typename detail::param<Point>::type value)
+{
+    BOOST_CONCEPT_ASSERT( (concept::Point<Point>) );
+
+    for_each_coordinate(p, detail::value_operation<typename coordinate_type<Point>::type, std::multiplies>(value));
+}
+
+/*!
+    \brief Multiplies a point by another
+    \ingroup arithmetic
+    \details The coordinates of the second point will be multiplied by those of the first point.
+             The second point is not modified.
+    \param p1 first point
+    \param p2 second point
+    \note This is *not* a dot, cross or wedge product. It is a mere field-by-field multiplication.
+ */
+template <typename Point1, typename Point2>
+inline void multiply_point(Point1& p1, Point2 const& p2)
+{
+    BOOST_CONCEPT_ASSERT( (concept::Point<Point2>) );
+    BOOST_CONCEPT_ASSERT( (concept::ConstPoint<Point2>) );
+
+    for_each_coordinate(p1, detail::point_operation<Point2, std::multiplies>(p2));
+}
+
+/*!
+    \brief Divides each coordinate of a point by a value
+    \ingroup arithmetic
+    \details
+    \param p point
+    \param value value to divide by
+ */
+template <typename Point>
+inline void divide_value(Point& p, typename detail::param<Point>::type value)
+{
+    BOOST_CONCEPT_ASSERT( (concept::Point<Point>) );
+
+    for_each_coordinate(p, detail::value_operation<typename coordinate_type<Point>::type, std::divides>(value));
+}
+
+/*!
+    \brief Divides a point by another
+    \ingroup arithmetic
+    \details The coordinates of the second point will be divided by those of the first point.
+             The second point is not modified.
+    \param p1 first point
+    \param p2 second point
+ */
+template <typename Point1, typename Point2>
+inline void divide_point(Point1& p1, Point2 const& p2)
+{
+    BOOST_CONCEPT_ASSERT( (concept::Point<Point2>) );
+    BOOST_CONCEPT_ASSERT( (concept::ConstPoint<Point2>) );
+
+    for_each_coordinate(p1, detail::point_operation<Point2, std::divides>(p2));
+}
+
+} // namespace ggl
+
+#endif // GGL_ARITHMETIC_ARITHMETIC_HPP
Added: sandbox/ggl/formal_review/boost/ggl/arithmetic/dot_product.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/arithmetic/dot_product.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,74 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ARITHMETIC_DOT_PRODUCT_HPP
+#define GGL_ARITHMETIC_DOT_PRODUCT_HPP
+
+#include <boost/concept/requires.hpp>
+
+#include <ggl/geometries/concepts/point_concept.hpp>
+#include <ggl/util/select_coordinate_type.hpp>
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+template <typename P1, typename P2, std::size_t Dimension, std::size_t DimensionCount>
+struct dot_product_maker
+{
+    typedef typename select_coordinate_type<P1, P2>::type coordinate_type;
+
+    static inline coordinate_type apply(P1 const& p1, P2 const& p2)
+    {
+        return get<Dimension>(p1) * get<Dimension>(p2)
+            + dot_product_maker<P1, P2, Dimension+1, DimensionCount>::apply(p1, p2);
+    }
+};
+
+template <typename P1, typename P2, std::size_t DimensionCount>
+struct dot_product_maker<P1, P2, DimensionCount, DimensionCount>
+{
+    typedef typename select_coordinate_type<P1, P2>::type coordinate_type;
+
+    static inline coordinate_type apply(P1 const& p1, P2 const& p2)
+    {
+        return get<DimensionCount>(p1) * get<DimensionCount>(p2);
+    }
+};
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+/*!
+    \brief Computes the dot product of 2 points
+    \ingroup arithmetic
+    \param p1 first point
+    \param p2 second point
+    \return the dot product
+ */
+template <typename P1, typename P2>
+inline typename select_coordinate_type<P1, P2>::type dot_product(
+        P1 const& p1, P2 const& p2)
+{
+    BOOST_CONCEPT_ASSERT( (concept::ConstPoint<P1>) );
+    BOOST_CONCEPT_ASSERT( (concept::ConstPoint<P2>) );
+
+    return detail::dot_product_maker
+        <
+            P1, P2,
+            0, dimension<P1>::type::value - 1
+        >::apply(p1, p2);
+}
+
+} // namespace ggl
+
+#endif // GGL_ARITHMETIC_DOT_PRODUCT_HPP
Added: sandbox/ggl/formal_review/boost/ggl/core/access.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/core/access.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,381 @@
+// Generic Geometry Library
+//
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_CORE_ACCESS_HPP
+#define GGL_CORE_ACCESS_HPP
+
+
+
+/*!
+\defgroup access access: get/set coordinate values, make objects, clear geometries, append point(s)
+\details There are many ways to edit geometries. It is possible to:
+- use the geometries themselves, so access point.x(). This is not done inside the library because it is agnostic
+ to geometry type. However, library users can use this as it is intuitive.
+- use the standard library, so use .push_back(point) or use inserters. This is also avoided inside the library.
+However, library users can use it if they are used to the standard library
+- use the functionality provided in this geometry library. These are the functions in this module.
+
+The library provides the following functions to edit geometries:
+- set to set one coordinate value
+- assign to set two or more coordinate values
+- make to construct and return geometries with specified coordinates.
+- append to append one or more points to a geometry
+- clear to remove all points from a geometry
+
+For getting coordinates it is similar:
+- get to get a coordinate value
+- or use the standard library
+- or use the geometries themselves
+
+*/
+
+#include <cstddef>
+
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/concept_check.hpp>
+
+#include <ggl/core/coordinate_type.hpp>
+#include <ggl/core/point_type.hpp>
+#include <ggl/core/tag.hpp>
+
+
+namespace ggl
+{
+
+const int min_corner = 0;
+const int max_corner = 1;
+
+namespace traits
+{
+
+/*!
+\brief Traits class which gives access (get,set) to points
+\ingroup traits
+\par Geometries:
+    - point
+\par Specializations should provide, per Dimension
+    - static inline T get(const G&)
+    - static inline void set(G&, T const&)
+\tparam Geometry geometry-type
+\tparam Dimension dimension to access
+*/
+template <typename Geometry, std::size_t Dimension>
+struct access {};
+
+
+/*!
+\brief Traits class defining "get" and "set" to get 
+    and set point coordinate values
+\tparam Geometry geometry (box, segment)
+\tparam Index index (min_corner/max_corner for box, 0/1 for segment)
+\tparam Dimension dimension
+\par Geometries:
+    - box
+    - segment
+\par Specializations should provide:
+    - static inline T get(const G&)
+    - static inline void set(G&, T const&)
+\ingroup traits
+*/
+template <typename Geometry, std::size_t Index, std::size_t Dimension>
+struct indexed_access {};
+
+
+/*!
+\brief Traits class, optional, indicating that the std-library should be used
+\details The default geometry (linestring, ring, multi*) follow std:: for
+    its modifying operations (push_back, clear, size, resize, reserve, etc)
+    If they NOT follow the std:: library they should specialize this traits
+    class
+\ingroup traits
+\par Geometries:
+    - linestring
+    - linear_ring
+\par Specializations should provide:
+    - value (defaults to true)
+ */
+template <typename Geometry>
+struct use_std
+{
+    static const bool value = true;
+};
+
+
+/*!
+\brief Traits class, optional, might be implemented to clear a geometry
+\details If a geometry type should not use the std ".clear()" 
+    then it can specialize the "use_std" traits class to false,
+    it should then implement (a.o.) clear
+\ingroup traits
+\par Geometries:
+    - linestring
+    - linear_ring
+\par Specializations should provide:
+    - apply
+ */
+template <typename Geometry>
+struct clear
+{};
+
+
+/*!
+\brief Traits class, optional, might be implemented to append a point
+\details If a geometry type should not use the std "push_back" 
+    then it can specialize the "use_std" traits class to false, 
+    it should then implement (a.o.) append_point
+\ingroup traits
+\par Geometries:
+    - linestring
+    - linear_ring
+\par Specializations should provide:
+    - apply
+ */
+template <typename Geometry, typename Point>
+struct append_point
+{};
+
+
+} // namespace traits
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+template
+<
+    typename Tag,
+    typename Geometry,
+    typename
+    CoordinateType, std::size_t Dimension
+>
+struct access
+{
+    //static inline T get(const G& ) {}
+    //static inline void set(G& g, T const& value) {}
+};
+
+template
+<
+    typename Tag,
+    typename Geometry,
+    typename CoordinateType,
+    std::size_t Index,
+    std::size_t Dimension
+>
+struct indexed_access
+{
+    //static inline T get(const G& ) {}
+    //static inline void set(G& g, T const& value) {}
+};
+
+template <typename Point, typename CoordinateType, std::size_t Dimension>
+struct access<point_tag, Point, CoordinateType, Dimension>
+{
+    static inline CoordinateType get(Point const& point)
+    {
+        return traits::access<Point, Dimension>::get(point);
+    }
+    static inline void set(Point& p, CoordinateType const& value)
+    {
+        traits::access<Point, Dimension>::set(p, value);
+    }
+};
+
+template
+<
+    typename Box,
+    typename CoordinateType,
+    std::size_t Index,
+    std::size_t Dimension
+>
+struct indexed_access<box_tag, Box, CoordinateType, Index, Dimension>
+{
+    static inline CoordinateType get(Box const& box)
+    {
+        return traits::indexed_access<Box, Index, Dimension>::get(box);
+    }
+    static inline void set(Box& b, CoordinateType const& value)
+    {
+        traits::indexed_access<Box, Index, Dimension>::set(b, value);
+    }
+};
+
+template
+<
+    typename Segment,
+    typename CoordinateType,
+    std::size_t Index,
+    std::size_t Dimension
+>
+struct indexed_access<segment_tag, Segment, CoordinateType, Index, Dimension>
+{
+    static inline CoordinateType get(Segment const& segment)
+    {
+        return traits::indexed_access<Segment, Index, Dimension>::get(segment);
+    }
+    static inline void set(Segment& segment, CoordinateType const& value)
+    {
+        traits::indexed_access<Segment, Index, Dimension>::set(segment, value);
+    }
+};
+
+} // namespace core_dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+// Two dummy tags to distinguish get/set variants below.
+// They don't have to be specified by the user. The functions are distinguished
+// by template signature also, but for e.g. GCC this is not enough. So give them
+// a different signature.
+struct signature_getset_dimension {};
+struct signature_getset_index_dimension {};
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+// Note the comments below tell Doxygen to create one function with doc for both
+
+/*!
+\brief 
+- get coordinate value of a Point ( / Sphere)
+\ingroup access
+\return coordinate value
+\tparam Index index
+- for Point: don't specify 
+- for Box: min_corner or max_corner
+- for Segment: 0 / 1
+\tparam Dimension dimension
+\tparam Geometry geometry
+\param geometry geometry to get coordinate value from
+*/
+template <std::size_t Dimension, typename Geometry>
+inline typename coordinate_type<Geometry>::type get(Geometry const& geometry
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+        , detail::signature_getset_dimension* dummy = 0
+#endif
+        )
+{
+    boost::ignore_unused_variable_warning(dummy);
+
+    typedef typename boost::remove_const<Geometry>::type ncg_type;
+
+    typedef core_dispatch::access
+        <
+            typename tag<Geometry>::type,
+            ncg_type,
+            typename coordinate_type<ncg_type>::type,
+            Dimension
+        > coord_access_type;
+
+    return coord_access_type::get(geometry);
+}
+
+
+/*!
+\brief 
+- set coordinate value of a Point ( / Sphere)
+\ingroup access
+\tparam Index index
+- for Point: don't specify 
+- for Box: min_corner or max_corner
+- for Segment: 0 / 1
+\tparam Dimension dimension
+\tparam Geometry geometry
+\param geometry geometry to assign coordinate to
+\param value coordinate value to assign
+*/
+template <std::size_t Dimension, typename Geometry>
+inline void set(Geometry& geometry
+        , typename coordinate_type<Geometry>::type const& value
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+        , detail::signature_getset_dimension* dummy = 0
+#endif
+        )
+{
+    boost::ignore_unused_variable_warning(dummy);
+
+    typedef typename boost::remove_const<Geometry>::type ncg_type;
+
+    typedef core_dispatch::access
+        <
+            typename tag<Geometry>::type,
+            ncg_type,
+            typename coordinate_type<ncg_type>::type,
+            Dimension
+        > coord_access_type;
+
+    coord_access_type::set(geometry, value);
+}
+
+// Note: doxygen needs a construct to distinguish get/set (like the gcc compiler)
+
+/*!
+\brief
+- get coordinate value of a Box / Segment
+\ingroup access
+*/
+template <std::size_t Index, std::size_t Dimension, typename Geometry>
+inline typename coordinate_type<Geometry>::type get(Geometry const& geometry
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+        , detail::signature_getset_index_dimension* dummy = 0
+#endif
+        )
+{
+    boost::ignore_unused_variable_warning(dummy);
+
+    typedef typename boost::remove_const<Geometry>::type ncg_type;
+
+    typedef core_dispatch::indexed_access
+        <
+            typename tag<Geometry>::type,
+            ncg_type,
+            typename coordinate_type<ncg_type>::type,
+            Index,
+            Dimension
+        > coord_access_type;
+
+    return coord_access_type::get(geometry);
+}
+
+/*!
+\brief 
+- set coordinate value of a Box / Segment
+\ingroup access
+*/
+template <std::size_t Index, std::size_t Dimension, typename Geometry>
+inline void set(Geometry& geometry
+        , typename coordinate_type<Geometry>::type const& value
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+        , detail::signature_getset_index_dimension* dummy = 0
+#endif
+        )
+{
+    boost::ignore_unused_variable_warning(dummy);
+
+    typedef typename boost::remove_const<Geometry>::type ncg_type;
+
+    typedef core_dispatch::indexed_access
+        <
+            typename tag<Geometry>::type, ncg_type,
+            typename coordinate_type<ncg_type>::type,
+            Index,
+            Dimension
+        > coord_access_type;
+
+    coord_access_type::set(geometry, value);
+}
+
+} // namespace ggl
+
+#endif // GGL_CORE_ACCESS_HPP
Added: sandbox/ggl/formal_review/boost/ggl/core/coordinate_dimension.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/core/coordinate_dimension.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,111 @@
+// Generic Geometry Library
+//
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_CORE_COORDINATE_DIMENSION_HPP
+#define GGL_CORE_COORDINATE_DIMENSION_HPP
+
+#include <cstddef>
+
+#include <boost/mpl/equal_to.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+#include <ggl/core/coordinate_dimension.hpp>
+#include <ggl/core/point_type.hpp>
+
+namespace ggl
+{
+
+namespace traits
+{
+
+/*!
+    \brief Traits class indicating the number of dimensions of a point
+    \par Geometries:
+        - point
+    \par Specializations should provide:
+        - value (should be derived from boost::mpl::int_<D>
+    \ingroup traits
+*/
+template <typename P>
+struct dimension {};
+
+} // namespace traits
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+// Base class derive from its own specialization of point-tag
+template <typename T, typename G>
+struct dimension : dimension<point_tag, typename point_type<T, G>::type> {};
+
+template <typename P>
+struct dimension<point_tag, P> : traits::dimension<P> {};
+
+} // namespace core_dispatch
+#endif
+
+/*!
+    \brief Meta-function which defines coordinate dimensions, i.e. the number of axes of any geometry
+    \ingroup core
+*/
+template <typename G>
+struct dimension
+    : core_dispatch::dimension
+        <
+        typename tag<G>::type,
+        typename boost::remove_const<G>::type
+        >
+{};
+
+/*!
+    \brief assert_dimension, enables compile-time checking if coordinate dimensions are as expected
+    \ingroup utility
+*/
+template <typename G, int D>
+inline void assert_dimension()
+{
+    BOOST_STATIC_ASSERT((
+        boost::mpl::equal_to
+        <
+        ggl::dimension<G>,
+        boost::mpl::int_<D>
+        >::type::value
+        ));
+}
+
+/*!
+    \brief assert_dimension, enables compile-time checking if coordinate dimensions are as expected
+    \ingroup utility
+*/
+template <typename G, int D>
+inline void assert_dimension_less_equal()
+{
+    BOOST_STATIC_ASSERT(( dimension<G>::type::value <= D ));
+}
+
+template <typename G, int D>
+inline void assert_dimension_greater_equal()
+{
+    BOOST_STATIC_ASSERT(( dimension<G>::type::value >= D ));
+}
+
+/*!
+    \brief assert_dimension_equal, enables compile-time checking if coordinate dimensions of two geometries are equal
+    \ingroup utility
+*/
+template <typename G1, typename G2>
+inline void assert_dimension_equal()
+{
+    BOOST_STATIC_ASSERT(( dimension<G1>::type::value == dimension<G2>::type::value ));
+}
+
+} // namespace ggl
+
+#endif // GGL_CORE_COORDINATE_DIMENSION_HPP
Added: sandbox/ggl/formal_review/boost/ggl/core/coordinate_system.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/core/coordinate_system.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,79 @@
+// Generic Geometry Library
+//
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_CORE_COORDINATE_SYSTEM_HPP
+#define GGL_CORE_COORDINATE_SYSTEM_HPP
+
+
+#include <boost/type_traits/remove_const.hpp>
+#include <ggl/core/point_type.hpp>
+
+
+namespace ggl
+{
+
+namespace traits
+{
+
+    /*!
+        \brief Traits class defining the coordinate system of a point, important for strategy selection
+        \ingroup traits
+        \par Geometries:
+            - point
+        \par Specializations should provide:
+            - typedef CS type; (cs::cartesian, cs::spherical, etc)
+    */
+    template <typename P>
+    struct coordinate_system {};
+
+} // namespace traits
+
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+    template <typename GeometryTag, typename G>
+    struct coordinate_system
+    {
+        typedef typename point_type<GeometryTag, G>::type P;
+
+        // Call its own specialization on point-tag
+        typedef typename coordinate_system<point_tag, P>::type type;
+    };
+
+
+    template <typename P>
+    struct coordinate_system<point_tag, P>
+    {
+        typedef typename traits::coordinate_system<P>::type type;
+    };
+
+
+} // namespace core_dispatch
+#endif
+
+
+/*!
+    \brief Meta-function which defines coordinate system for any geometry
+    \ingroup core
+*/
+template <typename G>
+struct coordinate_system
+{
+    typedef typename boost::remove_const<G>::type ncg;
+    typedef typename core_dispatch::coordinate_system<
+        typename tag<G>::type, ncg>::type type;
+};
+
+}
+
+
+#endif // GGL_CORE_COORDINATE_SYSTEM_HPP
Added: sandbox/ggl/formal_review/boost/ggl/core/coordinate_type.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/core/coordinate_type.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,72 @@
+// Generic Geometry Library
+//
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_CORE_COORDINATE_TYPE_HPP
+#define GGL_CORE_COORDINATE_TYPE_HPP
+
+#include <boost/type_traits/remove_const.hpp>
+
+#include <ggl/core/point_type.hpp>
+
+namespace ggl {
+
+namespace traits {
+
+/*!
+    \brief Traits class which indicate the coordinate type (double,float,...) of a point
+    \ingroup traits
+    \par Geometries:
+        - point
+    \par Specializations should provide:
+        - typedef T type; (double,float,int,etc)
+*/
+template <typename P>
+struct coordinate_type {};
+
+} // namespace traits
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+template <typename GeometryTag, typename G>
+struct coordinate_type
+{
+    typedef typename point_type<GeometryTag, G>::type point_type;
+
+    // Call its own specialization on point-tag
+    typedef typename coordinate_type<point_tag, point_type>::type type;
+};
+
+template <typename P>
+struct coordinate_type<point_tag, P>
+{
+    typedef typename traits::coordinate_type<P>::type type;
+};
+
+} // namespace core_dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+/*!
+    \brief Meta-function which defines coordinate type (int, float, double, etc) of any geometry
+    \ingroup core
+*/
+template <typename G>
+struct coordinate_type
+{
+    typedef typename boost::remove_const<G>::type ncg;
+    typedef typename core_dispatch::coordinate_type
+        <
+            typename tag<G>::type,
+            ncg
+        >::type type;
+};
+
+} // namespace ggl
+
+#endif // GGL_CORE_COORDINATE_TYPE_HPP
Added: sandbox/ggl/formal_review/boost/ggl/core/cs.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/core/cs.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,186 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_CORE_CS_HPP
+#define GGL_CORE_CS_HPP
+
+#include <cstddef>
+
+#include <boost/type_traits.hpp>
+
+#include <ggl/core/coordinate_system.hpp>
+#include <ggl/core/tags.hpp>
+
+/*!
+\defgroup cs coordinate systems
+\brief Defines coordinate systems
+\details Coordinate systems are essential for any point in the Generic Geometry Library. Many
+algorithms such as distance or transform use coordinate systems to select the strategy to use.
+*/
+
+namespace ggl
+{
+
+/*!
+    \brief Unit of plane angle: Degrees
+    \ingroup cs
+*/
+class degree {};
+
+
+/*!
+    \brief Unit of plane angle: Radians
+    \ingroup cs
+*/
+class radian {};
+
+
+namespace cs
+{
+
+/*!
+    \brief Cartesian coordinate system
+    \details Defines the Cartesian or rectangular coordinate system
+        where points are defined in 2 or 3 (or more)
+    dimensions and usually (but not always) known as x,y,z
+    \see http://en.wikipedia.org/wiki/Cartesian_coordinate_system
+    \ingroup cs
+*/
+struct cartesian {};
+
+
+
+
+/*!
+    \brief Geographic coordinate system, in degree or in radian
+    \details Defines the geographic coordinate system where points
+        are defined in two angles and usually
+    known as lat,long or lo,la or phi,lambda
+    \see http://en.wikipedia.org/wiki/Geographic_coordinate_system
+    \ingroup cs
+    \note might be moved to extensions/gis/geographic
+*/
+template<typename DegreeOrRadian>
+struct geographic
+{
+    typedef DegreeOrRadian units;
+};
+
+
+
+/*!
+    \brief Spherical coordinate system, in degree or in radian
+    \details Defines the spherical coordinate system where points are
+        defined in two angles
+        and an optional radius usually known as r, theta, phi
+    \par Coordinates:
+    - coordinate 0:
+        0 <= phi < 2pi is the angle between the positive x-axis and the
+            line from the origin to the P projected onto the xy-plane.
+    - coordinate 1:
+        0 <= theta <= pi is the angle between the positive z-axis and the
+            line formed between the origin and P.
+    - coordinate 2 (if specified):
+        r >= 0 is the distance from the origin to a given point P.
+
+    \see http://en.wikipedia.org/wiki/Spherical_coordinates
+    \ingroup cs
+*/
+template<typename DegreeOrRadian>
+struct spherical
+{
+    typedef DegreeOrRadian units;
+};
+
+/*!
+    \brief Polar coordinate system
+    \details Defines the polar coordinate system "in which each point
+        on a plane is determined by an angle and a distance"
+    \see http://en.wikipedia.org/wiki/Polar_coordinates
+    \ingroup cs
+*/
+template<typename DegreeOrRadian>
+struct polar
+{
+    typedef DegreeOrRadian units;
+};
+
+
+} // namespace cs
+
+namespace traits
+{
+/*!
+    \brief Traits class defining coordinate system tag, bound to coordinate system
+    \ingroup traits
+    \tparam CoordinateSystem coordinate system
+*/
+template <typename CoordinateSystem>
+struct cs_tag
+{
+};
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+template<typename DegreeOrRadian>
+struct cs_tag<cs::geographic<DegreeOrRadian> >
+{
+    typedef geographic_tag type;
+};
+
+template<typename DegreeOrRadian>
+struct cs_tag<cs::spherical<DegreeOrRadian> >
+{
+    typedef spherical_tag type;
+};
+
+template<>
+struct cs_tag<cs::cartesian>
+{
+    typedef cartesian_tag type;
+};
+
+
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+} // namespace traits
+
+/*!
+    \brief Meta-function returning coordinate system tag (cs family) of any geometry
+    \ingroup core
+*/
+template <typename G>
+struct cs_tag
+{
+    typedef typename traits::cs_tag
+        <
+            typename ggl::coordinate_system<G>::type
+        >::type type;
+};
+
+
+/*!
+    \brief Meta-function to verify if a coordinate system is radian
+    \ingroup core
+*/
+template <typename CoordinateSystem>
+struct is_radian : boost::true_type {};
+
+
+#ifndef DOXYGEN_NO_SPECIALIZATIONS
+
+// Specialization for any degree coordinate systems
+template <template<typename> class CoordinateSystem>
+struct is_radian< CoordinateSystem<degree> > : boost::false_type
+{
+};
+
+#endif // DOXYGEN_NO_SPECIALIZATIONS
+
+} // namespace ggl
+
+#endif // GGL_CORE_CS_HPP
Added: sandbox/ggl/formal_review/boost/ggl/core/exception.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/core/exception.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,26 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_CORE_EXCEPTION_HPP
+#define GGL_CORE_EXCEPTION_HPP
+
+#include <exception>
+
+namespace ggl {
+
+/*!
+\brief Base exception class for GGL
+\ingroup core
+*/
+struct exception : public std::exception
+{
+};
+
+} // namespace ggl
+
+#endif // GGL_CORE_EXCEPTION_HPP
Added: sandbox/ggl/formal_review/boost/ggl/core/exterior_ring.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/core/exterior_ring.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,128 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_CORE_EXTERIOR_RING_HPP
+#define GGL_CORE_EXTERIOR_RING_HPP
+
+
+#include <boost/type_traits/remove_const.hpp>
+
+
+#include <ggl/core/ring_type.hpp>
+#include <ggl/core/tag.hpp>
+#include <ggl/core/tags.hpp>
+#include <ggl/util/add_const_if_c.hpp>
+
+
+namespace ggl {
+
+namespace traits {
+
+
+/*!
+    \brief Traits class defining access to exterior_ring of a polygon
+    \details Should define const and non const access
+    \ingroup traits
+    \tparam Polygon the polygon type
+    \par Geometries:
+        - polygon
+    \par Specializations should provide:
+        - static inline RING& get(POLY& )
+        - static inline const RING& get(const POLY& )
+*/
+template <typename Polygon>
+struct exterior_ring
+{};
+
+
+} // namespace traits
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+
+template <typename Tag, typename Geometry, bool IsConst>
+struct exterior_ring {};
+
+
+template <typename Polygon, bool IsConst>
+struct exterior_ring<polygon_tag, Polygon, IsConst>
+{
+    static inline typename add_const_if_c
+        <
+            IsConst,
+            typename ggl::ring_type
+                    <
+                        Polygon
+                    >::type
+        >::type& apply(typename add_const_if_c
+            <
+                IsConst,
+                Polygon
+            >::type& polygon)
+    {
+        return traits::exterior_ring
+            <
+                typename boost::remove_const<Polygon>::type
+            >::get(polygon);
+    }
+};
+
+
+} // namespace core_dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+    \brief Function to get the exterior_ring ring of a polygon
+    \ingroup access
+    \note OGC compliance: instead of ExteriorRing
+    \tparam P polygon type
+    \param polygon the polygon to get the exterior ring from
+    \return a reference to the exterior ring
+*/
+template <typename Polygon>
+inline typename ring_type<Polygon>::type& exterior_ring(Polygon& polygon)
+{
+    return core_dispatch::exterior_ring
+        <
+            typename tag<Polygon>::type,
+            Polygon,
+            false
+        >::apply(polygon);
+}
+
+
+/*!
+    \brief Function to get the exterior ring of a polygon (const version)
+    \ingroup access
+    \note OGC compliance: instead of ExteriorRing
+    \tparam Polygon polygon type
+    \param polygon the polygon to get the exterior ring from
+    \return a const reference to the exterior ring
+*/
+template <typename Polygon>
+inline const typename ring_type<Polygon>::type& exterior_ring(
+        Polygon const& polygon)
+{
+    return core_dispatch::exterior_ring
+        <
+            typename tag<Polygon>::type,
+            Polygon,
+            true
+        >::apply(polygon);
+}
+
+
+} // namespace ggl
+
+
+#endif // GGL_CORE_EXTERIOR_RING_HPP
Added: sandbox/ggl/formal_review/boost/ggl/core/geometry_id.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/core/geometry_id.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,76 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_CORE_GEOMETRY_ID_HPP
+#define GGL_CORE_GEOMETRY_ID_HPP
+
+
+#include <boost/mpl/int.hpp>
+#include <boost/type_traits.hpp>
+
+
+#include <ggl/core/tag.hpp>
+#include <ggl/core/tags.hpp>
+
+
+namespace ggl {
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+template <typename GeometryTag>
+struct geometry_id {};
+
+
+template <>
+struct geometry_id<point_tag>      : boost::mpl::int_<1> {};
+
+
+template <>
+struct geometry_id<linestring_tag> : boost::mpl::int_<2> {};
+
+
+template <>
+struct geometry_id<polygon_tag>    : boost::mpl::int_<3> {};
+
+
+template <>
+struct geometry_id<segment_tag>    : boost::mpl::int_<92> {};
+
+
+template <>
+struct geometry_id<ring_tag>       : boost::mpl::int_<93> {};
+
+
+template <>
+struct geometry_id<box_tag>        : boost::mpl::int_<94> {};
+
+
+
+} // namespace core_dispatch
+#endif
+
+
+
+/*!
+    \brief Meta-function the id for a geometry type
+    \note Used for e.g. reverse meta-function
+    \ingroup core
+*/
+template <typename Geometry>
+struct geometry_id : core_dispatch::geometry_id<typename tag<Geometry>::type>
+{};
+
+
+} // namespace ggl
+
+
+#endif // GGL_CORE_GEOMETRY_ID_HPP
Added: sandbox/ggl/formal_review/boost/ggl/core/interior_rings.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/core/interior_rings.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,235 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_CORE_INTERIOR_RINGS_HPP
+#define GGL_CORE_INTERIOR_RINGS_HPP
+
+#include <cstddef>
+
+#include <boost/range/functions.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+#include <ggl/core/tag.hpp>
+#include <ggl/core/tags.hpp>
+#include <ggl/util/add_const_if_c.hpp>
+
+namespace ggl
+{
+
+namespace traits
+{
+
+/*!
+    \brief Traits class indicating interior container type of a polygon
+    \details defines inner container type, so the container containing
+            the interior rings
+    \ingroup traits
+    \par Geometries:
+        - polygon
+    \par Specializations should provide:
+        - typedef X type ( e.g. std::vector<myring<P>> )
+    \tparam Geometry geometry
+*/
+template <typename Geometry>
+struct interior_type
+{};
+
+
+/*!
+    \brief Traits class defining access to interior_rings of a polygon
+    \details defines access (const and non const) to interior ring
+    \ingroup traits
+    \par Geometries:
+        - polygon
+    \par Specializations should provide:
+        - static inline INTERIOR& get(POLY&)
+        - static inline const INTERIOR& get(const POLY&)
+    \tparam Geometry geometry
+*/
+template <typename Geometry>
+struct interior_rings
+{};
+
+
+} // namespace traits
+
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+
+template <typename GeometryTag, typename Geometry>
+struct interior_type
+{};
+
+
+template <typename Polygon>
+struct interior_type<polygon_tag, Polygon>
+{
+    typedef typename traits::interior_type
+        <
+            typename boost::remove_const<Polygon>::type
+        >::type type;
+};
+
+
+template
+<
+    typename GeometryTag,
+    typename Geometry,
+    bool IsConst
+>
+struct interior_rings {};
+
+
+template <typename Polygon, bool IsConst>
+struct interior_rings<polygon_tag, Polygon, IsConst>
+{
+    static inline typename add_const_if_c
+        <
+            IsConst,
+            typename interior_type
+                    <
+                        polygon_tag,
+                        Polygon
+                    >::type
+        >::type& apply(typename add_const_if_c
+            <
+                IsConst,
+                Polygon
+            >::type& polygon)
+    {
+        return traits::interior_rings
+            <
+                typename boost::remove_const<Polygon>::type
+            >::get(polygon);
+    }
+};
+
+
+template <typename Tag, typename Geometry>
+struct num_interior_rings
+{
+    static inline std::size_t apply(Geometry const&)
+    {
+        return 0;
+    }
+
+};
+
+
+template <typename Polygon>
+struct num_interior_rings<polygon_tag, Polygon>
+{
+    static inline std::size_t apply(Polygon const& polygon)
+    {
+        return boost::size(interior_rings
+            <
+                polygon_tag, Polygon, true
+            >::apply(polygon));
+    }
+
+};
+
+
+} // namespace core_dispatch
+#endif
+
+
+/*!
+    \brief Meta-function defining container type
+        of inner rings of (multi)polygon geometriy
+    \details the interior rings should be organized as a container
+        (std::vector, std::deque, boost::array) with
+        boost range support. This meta function defines the type
+            of that container.
+    \ingroup core
+*/
+template <typename Geometry>
+struct interior_type
+{
+    typedef typename core_dispatch::interior_type
+        <
+            typename tag<Geometry>::type,
+            Geometry
+        >::type type;
+};
+
+
+/*!
+    \brief Function to get the interior rings of a polygon (non const version)
+    \ingroup access
+    \note OGC compliance: instead of InteriorRingN
+    \tparam P polygon type
+    \param polygon the polygon to get the interior rings from
+    \return a reference to the interior rings
+*/
+template <typename Polygon>
+inline typename interior_type<Polygon>::type& interior_rings(Polygon& polygon)
+{
+    return core_dispatch::interior_rings
+        <
+            typename tag<Polygon>::type,
+            Polygon,
+            false
+        >::apply(polygon);
+}
+
+
+/*!
+    \brief Function to get the interior rings of a polygon (const version)
+    \ingroup access
+    \note OGC compliance: instead of InteriorRingN
+    \tparam P polygon type
+    \param polygon the polygon to get the interior rings from
+    \return a const reference to the interior rings
+*/
+template <typename Polygon>
+inline const typename interior_type<Polygon>::type& interior_rings(
+            Polygon const& polygon)
+{
+    return core_dispatch::interior_rings
+        <
+            typename tag<Polygon>::type,
+            Polygon,
+            true
+        >::apply(polygon);
+}
+
+
+
+/*!
+    \brief Function to get the number of interior rings of a polygon
+    \ingroup access
+    \note Defined by OGC as "numInteriorRing". To be consistent with "numPoints"
+        letter "s" is appended
+    \note Can be used for any geometry, returning 0 for geometries not having
+        interior rings
+    \tparam Geometry geometry type
+    \param geometry the polygon or other geometry
+    \return the number of interior rings of the geometry
+*/
+template <typename Geometry>
+inline std::size_t num_interior_rings(Geometry const& geometry)
+{
+    return core_dispatch::num_interior_rings
+        <
+            typename tag<Geometry>::type,
+            Geometry
+        >::apply(geometry);
+}
+
+
+}
+
+
+#endif // GGL_CORE_INTERIOR_RINGS_HPP
Added: sandbox/ggl/formal_review/boost/ggl/core/is_linear.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/core/is_linear.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,59 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_CORE_IS_LINEAR_HPP
+#define GGL_CORE_IS_LINEAR_HPP
+
+
+#include <boost/type_traits.hpp>
+
+
+#include <ggl/core/tag.hpp>
+#include <ggl/core/tags.hpp>
+
+
+namespace ggl {
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+template <typename GeometryTag>
+struct is_linear : boost::false_type {};
+
+
+template <>
+struct is_linear<linestring_tag> : boost::true_type {};
+
+
+template <>
+struct is_linear<ring_tag>       : boost::true_type {};
+
+
+} // namespace core_dispatch
+#endif
+
+
+
+/*!
+    \brief Meta-function defining "true" for linear types (linestring,ring),
+        "false" for non-linear typse
+    \note Used for tag dispatching and meta-function finetuning
+    \ingroup core
+*/
+template <typename Geometry>
+struct is_linear : core_dispatch::is_linear<typename tag<Geometry>::type>
+{};
+
+
+} // namespace ggl
+
+
+#endif // GGL_CORE_IS_LINEAR_HPP
Added: sandbox/ggl/formal_review/boost/ggl/core/is_multi.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/core/is_multi.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,49 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_CORE_IS_MULTI_HPP
+#define GGL_CORE_IS_MULTI_HPP
+
+
+#include <boost/type_traits.hpp>
+
+
+#include <ggl/core/tag.hpp>
+#include <ggl/core/tags.hpp>
+
+
+namespace ggl {
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+template <typename GeometryTag>
+struct is_multi : boost::false_type {};
+
+
+} // namespace core_dispatch
+#endif
+
+
+
+
+/*!
+    \brief Meta-function defining "true" for multi geometries (multi_point, etc)
+    \ingroup core
+*/
+template <typename Geometry>
+struct is_multi : core_dispatch::is_multi<typename tag<Geometry>::type>
+{};
+
+
+} // namespace ggl
+
+#endif // GGL_CORE_IS_MULTI_HPP
Added: sandbox/ggl/formal_review/boost/ggl/core/point_order.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/core/point_order.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,98 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_CORE_POINT_ORDER_HPP
+#define GGL_CORE_POINT_ORDER_HPP
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+#include <ggl/core/ring_type.hpp>
+#include <ggl/core/tag.hpp>
+#include <ggl/core/tags.hpp>
+
+namespace ggl {
+
+
+enum order_selector { clockwise = 1, counterclockwise = 2, order_undetermined = 0 };
+
+namespace traits {
+
+/*!
+    \brief Traits class indicating the order of contained points within a
+        ring or (multi)polygon, clockwise, counter clockwise or not known.
+    \ingroup traits
+    \par Geometries:
+        - ring
+        - polygon
+        - multi polygon
+    \par Specializations should provide:
+        - typedef P type (where P should fulfil the Point concept)
+    \tparam G geometry
+*/
+template <typename G>
+struct point_order
+{
+    static const order_selector value = clockwise;
+};
+
+
+} // namespace traits
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+template <typename Tag, typename Geometry>
+struct point_order
+{
+    static const order_selector value = clockwise;
+};
+
+
+
+template <typename Ring>
+struct point_order<ring_tag, Ring>
+{
+    static const order_selector value = ggl::traits::point_order<Ring>::value;
+};
+
+// Specialization for polygon: the order is the order of its rings
+template <typename Polygon>
+struct point_order<polygon_tag, Polygon>
+{
+    static const order_selector value = core_dispatch::point_order
+        <
+            ring_tag,
+            typename ring_type<polygon_tag, Polygon>::type
+        >::value ;
+};
+
+} // namespace core_dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+    \brief Meta-function which defines point type of any geometry
+    \ingroup core
+*/
+template <typename Geometry>
+struct point_order
+{
+    typedef typename boost::remove_const<Geometry>::type ncg;
+    static const order_selector value = core_dispatch::point_order
+        <
+            typename tag<Geometry>::type,
+            ncg
+        >::value;
+};
+
+} // namespace ggl
+
+#endif // GGL_CORE_POINT_ORDER_HPP
Added: sandbox/ggl/formal_review/boost/ggl/core/point_type.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/core/point_type.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,109 @@
+// Generic Geometry Library
+//
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_CORE_POINT_TYPE_HPP
+#define GGL_CORE_POINT_TYPE_HPP
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+#include <ggl/core/ring_type.hpp>
+#include <ggl/core/tag.hpp>
+#include <ggl/core/tags.hpp>
+
+namespace ggl {
+
+namespace traits {
+
+/*!
+    \brief Traits class indicating the type of contained points
+    \ingroup traits
+    \par Geometries:
+        - all geometries except point
+    \par Specializations should provide:
+        - typedef P type (where P should fulfil the Point concept)
+    \tparam G geometry
+*/
+template <typename G>
+struct point_type
+{};
+
+
+} // namespace traits
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+template <typename Tag, typename Geometry>
+struct point_type
+{
+    // Default: call traits to get point type
+    typedef typename boost::remove_const
+        <
+            typename traits::point_type<Geometry>::type
+        >::type type;
+};
+
+
+// Specialization for point: the point itself
+template <typename Point>
+struct point_type<point_tag, Point>
+{
+    typedef Point type;
+};
+
+// Specializations for linestring/linear ring, via boost::range
+template <typename Linestring>
+struct point_type<linestring_tag, Linestring>
+{
+    typedef typename boost::range_value<Linestring>::type type;
+};
+
+template <typename Ring>
+struct point_type<ring_tag, Ring>
+{
+    typedef typename boost::range_value<Ring>::type type;
+};
+
+// Specialization for polygon: the point-type is the point-type of its rings
+template <typename Polygon>
+struct point_type<polygon_tag, Polygon>
+{
+    typedef typename point_type
+        <
+            ring_tag,
+            typename ring_type<polygon_tag, Polygon>::type
+        >::type type;
+};
+
+} // namespace core_dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+    \brief Meta-function which defines point type of any geometry
+    \ingroup core
+*/
+template <typename Geometry>
+struct point_type
+{
+    typedef typename boost::remove_const<Geometry>::type ncg;
+    typedef typename core_dispatch::point_type<
+        typename tag<Geometry>::type, ncg>::type type;
+
+
+
+
+};
+
+} // namespace ggl
+
+#endif // GGL_CORE_POINT_TYPE_HPP
Added: sandbox/ggl/formal_review/boost/ggl/core/radian_access.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/core/radian_access.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,133 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_CORE_RADIAN_ACCESS_HPP
+#define GGL_CORE_RADIAN_ACCESS_HPP
+
+
+#include <cstddef>
+
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/cs.hpp>
+
+
+#include <ggl/util/math.hpp>
+
+
+namespace ggl {
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail {
+
+template <std::size_t Dimension, typename Geometry, typename DegreeOrRadian>
+struct radian_access
+{
+};
+
+template
+<
+    std::size_t Dimension,
+    typename Geometry,
+    template<typename> class CoordinateSystem
+>
+struct radian_access<Dimension, Geometry, CoordinateSystem<radian> >
+{
+    typedef typename coordinate_type<Geometry>::type coordinate_type;
+
+    static inline coordinate_type get(Geometry const& geometry)
+    {
+        return ggl::get<Dimension>(geometry);
+    }
+
+    static inline void set(Geometry& geometry, coordinate_type const& radians)
+    {
+        ggl::set<Dimension>(geometry, radians);
+    }
+};
+
+template
+<
+    std::size_t Dimension,
+    typename Geometry,
+    template<typename> class CoordinateSystem
+>
+struct radian_access<Dimension, Geometry, CoordinateSystem<degree> >
+{
+    typedef typename coordinate_type<Geometry>::type coordinate_type;
+
+    static inline coordinate_type get(Geometry const& geometry)
+    {
+        return boost::numeric_cast
+            <
+                coordinate_type
+            >(ggl::get<Dimension>(geometry) * ggl::math::d2r);
+    }
+
+    static inline void set(Geometry& geometry, coordinate_type const& radians)
+    {
+        ggl::set<Dimension>(geometry, boost::numeric_cast
+            <
+                coordinate_type
+            >(radians * ggl::math::r2d));
+    }
+
+};
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+/*!
+    \brief get coordinate value of a point, result is in Radian
+    \details Result is in Radian, even if source coordinate system
+        is in Degrees
+    \return coordinate value
+    \ingroup access
+    \tparam Dimension dimension
+    \tparam Geometry geometry
+    \param geometry geometry to get coordinate value from
+    \note Only applicable to coordinate systems templatized by units,
+        e.g. spherical or geographic coordinate systems
+*/
+template <std::size_t Dimension, typename Geometry>
+inline typename coordinate_type<Geometry>::type get_as_radian(const Geometry& geometry)
+{
+    return detail::radian_access<Dimension, Geometry,
+            typename coordinate_system<Geometry>::type>::get(geometry);
+}
+
+
+/*!
+    \brief set coordinate value (in radian) to a point
+    \details Coordinate value will be set correctly, if coordinate system of
+        point is in Degree, Radian value will be converted to Degree
+    \ingroup access
+    \tparam Dimension dimension
+    \tparam Geometry geometry
+    \param geometry geometry to assign coordinate to
+    \param radians coordinate value to assign
+    \note Only applicable to coordinate systems templatized by units,
+        e.g. spherical or geographic coordinate systems
+*/
+template <std::size_t Dimension, typename Geometry>
+inline void set_from_radian(Geometry& geometry,
+            const typename coordinate_type<Geometry>::type& radians)
+{
+    detail::radian_access<Dimension, Geometry,
+            typename coordinate_system<Geometry>::type>::set(geometry, radians);
+}
+
+
+} // namespace ggl
+
+
+#endif // GGL_CORE_RADIAN_ACCESS_HPP
Added: sandbox/ggl/formal_review/boost/ggl/core/replace_point_type.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/core/replace_point_type.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,92 @@
+// Generic Geometry Library
+//
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_CORE_REPLACE_POINT_TYPE_HPP
+#define GGL_CORE_REPLACE_POINT_TYPE_HPP
+
+
+#include <boost/type_traits/remove_const.hpp>
+
+
+#include <ggl/core/tag.hpp>
+#include <ggl/core/tags.hpp>
+#include <ggl/core/coordinate_type.hpp>
+
+// For now: use ggl-provided geometries
+// TODO: figure out how to get the class and replace the type
+// TODO: take "const" into account
+#include <ggl/geometries/point.hpp>
+#include <ggl/geometries/linestring.hpp>
+#include <ggl/geometries/linear_ring.hpp>
+#include <ggl/geometries/polygon.hpp>
+#include <ggl/geometries/segment.hpp>
+#include <ggl/geometries/box.hpp>
+
+
+namespace ggl {
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+template <typename GeometryTag, typename Geometry, typename NewPointType>
+struct replace_point_type {};
+
+template <typename Geometry, typename NewPointType>
+struct replace_point_type<point_tag, Geometry, NewPointType>
+{
+    typedef NewPointType type;
+};
+
+template <typename Geometry, typename NewPointType>
+struct replace_point_type<linestring_tag, Geometry, NewPointType>
+{
+    typedef linestring<NewPointType> type;
+};
+
+template <typename Geometry, typename NewPointType>
+struct replace_point_type<segment_tag, Geometry, NewPointType>
+{
+    typedef segment<NewPointType> type;
+};
+
+template <typename Geometry, typename NewPointType>
+struct replace_point_type<ring_tag, Geometry, NewPointType>
+{
+    typedef linear_ring<NewPointType> type;
+};
+
+template <typename Geometry, typename NewPointType>
+struct replace_point_type<box_tag, Geometry, NewPointType>
+{
+    typedef box<NewPointType> type;
+};
+
+template <typename Geometry, typename NewPointType>
+struct replace_point_type<polygon_tag, Geometry, NewPointType>
+{
+    typedef polygon<NewPointType> type;
+};
+
+
+} // namespace core_dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+template <typename Geometry, typename NewPointType>
+struct replace_point_type : core_dispatch::replace_point_type
+        <
+        typename tag<Geometry>::type,
+        typename boost::remove_const<Geometry>::type,
+        NewPointType
+        >
+{};
+
+} // namespace ggl
+
+#endif // GGL_CORE_REPLACE_POINT_TYPE_HPP
Added: sandbox/ggl/formal_review/boost/ggl/core/reverse_dispatch.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/core/reverse_dispatch.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,59 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_CORE_REVERSE_DISPATCH_HPP
+#define GGL_CORE_REVERSE_DISPATCH_HPP
+
+
+#include <boost/type_traits.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/greater.hpp>
+
+#include <ggl/core/geometry_id.hpp>
+
+
+namespace ggl {
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+// Different geometries: reverse_dispatch if second ID < first ID
+template <std::size_t GeometryId1, std::size_t GeometryId2>
+struct reverse_dispatch : boost::mpl::if_c
+<
+    (GeometryId1 > GeometryId2),
+    boost::true_type,
+    boost::false_type
+>
+{};
+
+
+// Same geometry: never reverse_dispatch
+template <std::size_t GeometryId>
+struct reverse_dispatch<GeometryId, GeometryId> : boost::false_type {};
+
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+template <typename Geometry1, typename Geometry2>
+struct reverse_dispatch : detail::reverse_dispatch
+    <
+    geometry_id<Geometry1>::type::value,
+    geometry_id<Geometry2>::type::value
+    >
+{};
+
+
+} // namespace ggl
+
+#endif // GGL_CORE_REVERSE_DISPATCH_HPP
Added: sandbox/ggl/formal_review/boost/ggl/core/ring_type.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/core/ring_type.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,95 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_CORE_RING_TYPE_HPP
+#define GGL_CORE_RING_TYPE_HPP
+
+
+#include <boost/type_traits/remove_const.hpp>
+
+
+#include <ggl/core/tag.hpp>
+#include <ggl/core/tags.hpp>
+
+
+namespace ggl
+{
+
+namespace traits
+{
+
+
+/*!
+    \brief Traits class to indicate ring-type  of a polygon's exterior ring/interior rings
+    \ingroup traits
+    \par Geometries:
+        - polygon
+    \par Specializations should provide:
+        - typedef XXX type ( e.g. linear_ring<P> )
+    \tparam Geometry geometry
+*/
+template <typename Geometry>
+struct ring_type
+{
+    // should define type
+};
+
+
+} // namespace traits
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+
+template <typename GeometryTag, typename Geometry>
+struct ring_type
+{};
+
+
+template <typename Polygon>
+struct ring_type<polygon_tag, Polygon>
+{
+    typedef typename traits::ring_type
+        <
+            typename boost::remove_const<Polygon>::type
+        >::type type;
+
+};
+
+
+} // namespace core_dispatch
+#endif
+
+
+/*!
+    \brief Meta-function which defines ring type of (multi)polygon geometry
+    \details a polygon contains one exterior ring
+        and zero or more interior rings (holes).
+        This meta function retrieves the type of the rings
+    \note Exterior ring and interior rings must have the same ring-type.
+    \ingroup core
+*/
+template <typename Geometry>
+struct ring_type
+{
+    typedef typename core_dispatch::ring_type
+        <
+            typename tag<Geometry>::type,
+            Geometry
+        >::type type;
+};
+
+
+}
+
+
+#endif // GGL_CORE_RING_TYPE_HPP
Added: sandbox/ggl/formal_review/boost/ggl/core/tag.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/core/tag.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,65 @@
+// Generic Geometry Library
+//
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_CORE_TAG_HPP
+#define GGL_CORE_TAG_HPP
+
+#include <boost/type_traits/remove_const.hpp>
+
+#include <ggl/core/tags.hpp>
+
+/*!
+\defgroup core core: meta-functions for geometry types
+*/
+
+namespace ggl
+{
+
+namespace traits
+{
+
+/*!
+    \brief Traits class to attach a tag to a geometry
+    \details All geometries should implement a traits::tag<G>::type metafunction to indicate their
+        own geometry type.
+    \ingroup traits
+    \par Geometries:
+        - all geometries
+    \par Specializations should provide:
+        - typedef XXX_tag type; (point_tag, box_tag, ...)
+    \tparam Geometry geometry
+*/
+template <typename Geometry>
+struct tag
+{
+    typedef geometry_not_recognized_tag type;
+};
+
+} // namespace traits
+
+
+/*!
+    \brief Meta-function to get the tag of any geometry type
+    \details All geometries tell their geometry type (point, linestring, polygon, etc) by implementing
+      a tag traits class. This meta-function uses that traits class to retrieve the tag.
+      If the input type is not a geometry at all, a geometry_not_recognized_tag will be returned.
+    \tparam Geometry geometry
+    \ingroup core
+*/
+template <typename Geometry>
+struct tag
+{
+    typedef typename traits::tag
+        <
+        typename boost::remove_const<Geometry>::type
+        >::type type;
+};
+
+} // namespace ggl
+
+#endif // GGL_CORE_TAG_HPP
Added: sandbox/ggl/formal_review/boost/ggl/core/tags.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/core/tags.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,61 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_CORE_TAGS_HPP
+#define GGL_CORE_TAGS_HPP
+
+
+/*!
+\defgroup traits traits: adapt geometries
+\brief Traits classes are small classes or structs to adapt geometries
+such that they are recognized by the Generic Geometry Library
+*/
+
+namespace ggl
+{
+
+// Tags defining strategies linked to coordinate systems
+
+
+/// Tag indicating Cartesian coordinate system family (cartesian,epsg)
+struct cartesian_tag {};
+
+/// Tag indicating Geographic coordinate system family (geographic)
+struct geographic_tag {};
+
+/// Tag indicating Spherical coordinate system family (spherical,celestial,...)
+struct spherical_tag {};
+
+
+// Tags defining geometry types
+
+
+/// "default" tag
+struct geometry_not_recognized_tag {};
+
+/// OGC Point identifying tag
+struct point_tag {};
+
+/// OGC Linestring identifying tag
+struct linestring_tag {};
+
+/// OGC Polygon identifying tag
+struct polygon_tag {};
+
+/// Convenience (linear) ring identifying tag
+struct ring_tag {};
+
+/// Convenience 2D or 3D box (mbr) identifying tag
+struct box_tag {};
+
+/// Convenience segment (2-points) identifying tag
+struct segment_tag {};
+
+} // namespace ggl
+
+#endif // GGL_CORE_TAGS_HPP
Added: sandbox/ggl/formal_review/boost/ggl/core/topological_dimension.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/core/topological_dimension.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,82 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_CORE_TOPOLOGICAL_DIMENSION_HPP
+#define GGL_CORE_TOPOLOGICAL_DIMENSION_HPP
+
+
+#include <boost/mpl/int.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+
+#include <ggl/core/tag.hpp>
+#include <ggl/core/tags.hpp>
+
+
+namespace ggl {
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch {
+
+
+template <typename GeometryTag>
+struct top_dim {};
+
+
+template <>
+struct top_dim<point_tag>      : boost::mpl::int_<0> {};
+
+
+template <>
+struct top_dim<linestring_tag> : boost::mpl::int_<1> {};
+
+
+template <>
+struct top_dim<segment_tag>    : boost::mpl::int_<1> {};
+
+
+// ring: topological dimension of two, but some people say: 1 !!
+template <>
+struct top_dim<ring_tag>       : boost::mpl::int_<2> {};
+
+
+template <>
+struct top_dim<box_tag>        : boost::mpl::int_<2> {};
+
+
+template <>
+struct top_dim<polygon_tag>    : boost::mpl::int_<2> {};
+
+
+
+} // namespace core_dispatch
+#endif
+
+
+
+
+
+/*!
+    \brief Meta-function returning the topological dimension of a geometry
+    \details The topological dimension defines a point as 0-dimensional,
+        a linestring as 1-dimensional,
+        and a ring or polygon as 2-dimensional.
+    \see http://www.math.okstate.edu/mathdept/dynamics/lecnotes/node36.html
+    \ingroup core
+*/
+template <typename Geometry>
+struct topological_dimension
+    : core_dispatch::top_dim<typename tag<Geometry>::type> {};
+
+
+} // namespace ggl
+
+
+#endif // GGL_CORE_TOPOLOGICAL_DIMENSION_HPP
Added: sandbox/ggl/formal_review/boost/ggl/extensions/gis/geographic/detail/ellipsoid.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/extensions/gis/geographic/detail/ellipsoid.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,58 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_EXTENSIONS_GIS_GEOGRAPHIC_DETAIL_ELLIPSOID_HPP
+#define GGL_EXTENSIONS_GIS_GEOGRAPHIC_DETAIL_ELLIPSOID_HPP
+
+
+namespace ggl { namespace detail {
+
+
+/*!
+    \brief Defines ellipsoid values for use in distance calculations
+    \details They have a constructor with the earth radius
+    \note Will be moved / merged with projections
+    \todo Optionally specify earth model, defaulting to WGS84
+    - See http://en.wikipedia.org/wiki/Figure_of_the_Earth
+    - and http://en.wikipedia.org/wiki/World_Geodetic_System#A_new_World_Geodetic_System:_WGS84
+    \note
+*/
+class ellipsoid
+{
+    public :
+        ellipsoid(double a, double b)
+            : m_a(a)
+            , m_b(b)
+            , m_f((a - b) / a)
+        {}
+        ellipsoid()
+            : m_a(6378137.0)
+            , m_b(6356752.314245)
+            , m_f((m_a - m_b) / m_a)
+        {}
+        // Unit sphere
+        ellipsoid(double f)
+            : m_a(1.0)
+            , m_f(f)
+        {}
+
+        double a() const { return m_a; }
+        double b() const { return m_b; }
+        double f() const { return m_f; }
+
+    private :
+        double m_a, m_b, m_f; // equatorial radius, polar radius, flattening
+};
+
+
+
+
+}} // namespace ggl::detail
+
+
+#endif // GGL_EXTENSIONS_GIS_GEOGRAPHIC_DETAIL_ELLIPSOID_HPP
Added: sandbox/ggl/formal_review/boost/ggl/extensions/gis/geographic/strategies/andoyer.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/extensions/gis/geographic/strategies/andoyer.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,142 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_EXTENSIONS_GIS_GEOGRAPHIC_STRATEGIES_ANDOYER_HPP
+#define GGL_EXTENSIONS_GIS_GEOGRAPHIC_STRATEGIES_ANDOYER_HPP
+
+
+#include <ggl/strategies/distance.hpp>
+#include <ggl/core/radian_access.hpp>
+#include <ggl/core/coordinate_type.hpp>
+
+#include <ggl/extensions/gis/geographic/detail/ellipsoid.hpp>
+
+
+namespace ggl
+{
+namespace strategy
+{
+
+    namespace distance
+    {
+
+
+        /*!
+            \brief Point-point distance approximation taking flattening into account
+            \ingroup distance
+            \tparam P1 first point type
+            \tparam P2 optional second point type
+            \author After Andoyer, 19xx, republished 1950, republished by Meeus, 1999
+            \note Although not so well-known, the approximation is very good: in all cases the results
+            are about the same as Vincenty. In my (Barend's) testcases the results didn't differ more than 6 m
+            \see http://nacc.upc.es/tierra/node16.html
+            \see http://sci.tech-archive.net/Archive/sci.geo.satellite-nav/2004-12/2724.html
+            \see http://home.att.net/~srschmitt/great_circle_route.html (implementation)
+            \see http://www.codeguru.com/Cpp/Cpp/algorithms/article.php/c5115 (implementation)
+            \see http://futureboy.homeip.net/frinksamp/navigation.frink (implementation)
+            \see http://www.voidware.com/earthdist.htm (implementation)
+        */
+        template <typename P1, typename P2 = P1>
+        class andoyer
+        {
+            public :
+                //typedef spherical_distance return_type;
+                typedef P1 first_point_type;
+                typedef P2 second_point_type;
+                typedef double return_type;
+
+                andoyer()
+                    : m_ellipsoid()
+                {}
+                andoyer(double f)
+                    : m_ellipsoid(f)
+                {}
+
+                inline return_type apply(const P1& p1, const P2& p2) const
+                {
+                    return calc(get_as_radian<0>(p1), get_as_radian<1>(p1),
+                                    get_as_radian<0>(p2), get_as_radian<1>(p2));
+                }
+
+
+            private :
+                typedef typename coordinate_type<P1>::type T1;
+                typedef typename coordinate_type<P2>::type T2;
+                ggl::detail::ellipsoid m_ellipsoid;
+
+                inline return_type calc(const T1& lon1, const T1& lat1, const T2& lon2, const T2& lat2) const
+                {
+                    typedef double calculation_type;
+                    calculation_type G = (lat1 - lat2) / 2.0;
+                    calculation_type lambda = (lon1 - lon2) / 2.0;
+
+                    if (ggl::math::equals(lambda, 0.0)
+                        && ggl::math::equals(G, 0.0))
+                    {
+                        return 0.0;
+                    }
+
+                    calculation_type F = (lat1 + lat2) / 2.0;
+
+                    calculation_type sinG2 = math::sqr(sin(G));
+                    calculation_type cosG2 = math::sqr(cos(G));
+                    calculation_type sinF2 = math::sqr(sin(F));
+                    calculation_type cosF2 = math::sqr(cos(F));
+                    calculation_type sinL2 = math::sqr(sin(lambda));
+                    calculation_type cosL2 = math::sqr(cos(lambda));
+
+                    calculation_type S = sinG2 * cosL2 + cosF2 * sinL2;
+                    calculation_type C = cosG2 * cosL2 + sinF2 * sinL2;
+
+                    if (ggl::math::equals(S, 0.0) || ggl::math::equals(C, 0.0))
+                    {
+                        return 0.0;
+                    }
+
+                    calculation_type omega = atan(sqrt(S / C));
+                    calculation_type r = sqrt(S * C) / omega; // not sure if this is r or greek nu
+
+                    calculation_type D = 2.0 * omega * m_ellipsoid.a();
+                    calculation_type H1 = (3 * r - 1.0) / (2.0 * C);
+                    calculation_type H2 = (3 * r + 1.0) / (2.0 * S);
+
+                    return return_type(D
+                        * (1.0 + m_ellipsoid.f() * H1 * sinF2 * cosG2
+                                    - m_ellipsoid.f() * H2 * cosF2 * sinG2));
+                }
+        };
+
+
+
+    } // namespace distance
+
+
+} // namespace strategy
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+template <typename P1, typename P2>
+struct strategy_distance<geographic_tag, geographic_tag, P1, P2>
+{
+    typedef strategy::distance::andoyer<P1, P2> type;
+};
+
+
+template <typename P1, typename P2>
+struct strategy_tag<strategy::distance::andoyer<P1, P2> >
+{
+    typedef strategy_tag_distance_point_point type;
+};
+
+#endif
+
+
+} // namespace ggl
+
+
+#endif // GGL_EXTENSIONS_GIS_GEOGRAPHIC_STRATEGIES_ANDOYER_HPP
Added: sandbox/ggl/formal_review/boost/ggl/extensions/gis/geographic/strategies/area_huiller_earth.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/extensions/gis/geographic/strategies/area_huiller_earth.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,60 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_EXTENSIONS_GIS_GEOGRAPHIC_STRATEGIES_AREA_HUILLER_EARTH_HPP
+#define GGL_EXTENSIONS_GIS_GEOGRAPHIC_STRATEGIES_AREA_HUILLER_EARTH_HPP
+
+
+
+#include <ggl/strategies/spherical/area_huiller.hpp>
+
+
+namespace ggl
+{
+
+namespace strategy { namespace area {
+
+
+
+template
+<
+    typename PointOfSegment,
+    typename CalculationType = void
+>
+class huiller_earth
+    : public huiller<PointOfSegment, CalculationType>
+{
+public :
+    // By default the average earth radius.
+    // Uses can specify another radius.
+    // Note that the earth is still spherical
+    inline huiller_earth(double radius = 6372795.0)
+        : huiller<PointOfSegment, CalculationType>(radius)
+    {}
+};
+
+
+
+}} // namespace strategy::area
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+template <typename Point>
+struct strategy_area<geographic_tag, Point>
+{
+    typedef strategy::area::huiller_earth<Point> type;
+};
+
+#endif
+
+
+} // namespace ggl
+
+
+#endif // GGL_EXTENSIONS_GIS_GEOGRAPHIC_STRATEGIES_AREA_HUILLER_EARTH_HPP
Added: sandbox/ggl/formal_review/boost/ggl/extensions/gis/geographic/strategies/dms_parser.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/extensions/gis/geographic/strategies/dms_parser.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,267 @@
+// Generic Geometry Library
+
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_EXTENSIONS_GIS_GEOGRAPHIC_STRATEGIES_DMS_PARSER_HPP
+#define GGL_EXTENSIONS_GIS_GEOGRAPHIC_STRATEGIES_DMS_PARSER_HPP
+
+// This file is totally revised from PROJ4 dmstor.c
+
+// PROJ4 is originally written by Gerald Evenden (then of the USGS)
+// PROJ4 is maintained by Frank Warmerdam
+// PROJ4 is converted to Geometry Library by Barend Gehrels (Geodan, Amsterdam)
+
+// Original copyright notice:
+
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include <string>
+
+#include <boost/static_assert.hpp>
+#include <boost/lexical_cast.hpp>
+#include <boost/algorithm/string.hpp>
+
+#include <ggl/core/cs.hpp>
+#include <ggl/strategies/parse.hpp>
+
+#include <ggl/util/math.hpp>
+
+namespace ggl
+{
+
+
+struct dms_result
+{
+    enum axis_selector {axis_lat = 1, axis_lon = 0};
+
+    private :
+        typedef double T;
+        T m_angle;
+        axis_selector m_axis;
+
+    public :
+
+        explicit dms_result(const T& v, axis_selector ax)
+            : m_angle(v)
+            , m_axis(ax)
+        {}
+
+        inline axis_selector axis() const { return m_axis; }
+
+        inline operator double() const { return m_angle; }
+
+        template <typename CH, typename TR>
+        inline friend std::basic_ostream<CH, TR>& operator<<(std::basic_ostream<CH, TR>& os,
+                        const dms_result& d)
+        {
+            os << d.m_angle;
+            return os;
+        }
+
+};
+
+
+namespace strategy
+{
+
+    template <bool as_radian = true
+            , char N = 'N', char E = 'E', char S = 'S', char W = 'W' // translatable
+            , char MIN = '\'', char SEC = '"' // other char's possible
+            , char D = 'D', char R = 'R' // degree sign might be small o
+            >
+    struct dms_parser
+    {
+
+
+        // Question from Barend: can we compile-time select that it is case-sensitive/case-insensitive?
+        // We have to change the switch then -> specializations
+
+        // For now: make it (compile-time) case sensitive
+        static const int diff = 'a' - 'A';
+#ifndef __GNUC__
+        BOOST_STATIC_ASSERT((diff > 0)); // make sure we've the right assumption. GCC does not accept this here.
+#endif
+        static const char n_alter = N <= 'Z' ? N + diff : N - diff;
+        static const char e_alter = E <= 'Z' ? E + diff : E - diff;
+        static const char s_alter = S <= 'Z' ? S + diff : S - diff;
+        static const char w_alter = W <= 'Z' ? W + diff : W - diff;
+
+        static const char r_alter = R <= 'Z' ? R + diff : R - diff;
+
+        // degree is normally D (proj4) but might be superscript o
+        // Note d_alter is not correct then, so map it to NULL now, guarded by the while
+        static const char d_alter =
+            ((D >= 'A' && D <= 'Z') || (D >= 'a' && D <= 'z')) ? (D <= 'Z' ? D + diff : D - diff) : '\0';
+
+
+        struct dms_value
+        {
+            double dms[3];
+            bool has_dms[3];
+
+            dms_value()
+            {
+                memset(this, 0, sizeof(dms_value));
+            }
+        };
+
+
+        template <size_t I>
+        static inline void assign_dms(dms_value& dms, std::string& value, bool& has_value)
+        {
+            dms.dms[I] = boost::lexical_cast<double>(value.c_str());
+            dms.has_dms[I] = true;
+            has_value = false;
+            value.clear();
+        }
+
+        static inline void process(dms_value& dms, std::string& value, bool& has_value)
+        {
+            if (has_value)
+            {
+                // Assign last one, sequentially
+                if (! dms.has_dms[0]) assign_dms<0>(dms, value, has_value);
+                else if (! dms.has_dms[1]) assign_dms<1>(dms, value, has_value);
+                else if (! dms.has_dms[2]) assign_dms<2>(dms, value, has_value);
+            }
+        }
+
+
+        dms_result operator()(const char* is) const
+        {
+            dms_value dms;
+            bool has_value = false;
+            std::string value;
+
+            double factor = 1.0; // + denotes N/E values, -1 denotes S/W values
+            dms_result::axis_selector axis = dms_result::axis_lon; // true denotes N/S values
+            bool in_radian = false; // true denotes values as "0.1R"
+
+            while(*is)
+            {
+                switch(*is)
+                {
+                    case '-' :
+                        if (! has_value && ! dms.has_dms[0])
+                        {
+                            factor = -factor;
+                        }
+                        break;
+                    case N :
+                    case n_alter :
+                        axis = dms_result::axis_lat;
+                        break;
+                    case S :
+                    case s_alter :
+                        axis = dms_result::axis_lat;
+                        factor = -factor;
+                        break;
+                    case E :
+                    case e_alter :
+                        axis = dms_result::axis_lon;
+                        break;
+                    case W :
+                    case w_alter :
+                        axis = dms_result::axis_lon;
+                        factor = -factor;
+                        break;
+                    case D :
+                    case d_alter :
+                        if (! dms.has_dms[0] && has_value)
+                        {
+                            assign_dms<0>(dms, value, has_value);
+                        }
+                        break;
+                    case R :
+                    case r_alter :
+                        if (! dms.has_dms[0] && has_value)
+                        {
+                            // specified value is in radian!
+                            in_radian = true;
+                            assign_dms<0>(dms, value, has_value);
+                        }
+                        break;
+                    case MIN:
+                        if (! dms.has_dms[1] && has_value)
+                        {
+                            assign_dms<1>(dms, value, has_value);
+                        }
+                        break;
+                    case SEC :
+                        if (! dms.has_dms[2] && has_value)
+                        {
+                            assign_dms<2>(dms, value, has_value);
+                        }
+                        break;
+                    case ' ' :
+                    case '\t' :
+                    case '\n' :
+                        process(dms, value, has_value);
+                        break;
+                    default :
+                        value += *is;
+                        has_value = true;
+                        break;
+                }
+                is++;
+            }
+
+            // Assign last one, if any
+            process(dms, value, has_value);
+
+            return dms_result(factor *
+                (in_radian && as_radian
+                        ? dms.dms[0]
+                : in_radian && ! as_radian
+                        ? dms.dms[0] * math::r2d
+                : ! in_radian && as_radian
+                        ? dms.dms[0] * math::d2r + dms.dms[1] * math::d2r / 60.0 + dms.dms[2] * math::d2r / 3600.0
+                        : dms.dms[0] + dms.dms[1] / 60.0 + dms.dms[2] / 3600.0)
+                , axis);
+        }
+    };
+
+}
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+template <template<typename> class CS>
+struct strategy_parse<geographic_tag, CS<degree> >
+{
+    typedef strategy::dms_parser<false> type;
+};
+
+
+template <template<typename> class CS>
+struct strategy_parse<geographic_tag, CS<radian> >
+{
+    typedef strategy::dms_parser<true> type;
+};
+
+#endif
+
+
+} // namespace ggl
+
+#endif // GGL_EXTENSIONS_GIS_GEOGRAPHIC_STRATEGIES_DMS_PARSER_HPP
Added: sandbox/ggl/formal_review/boost/ggl/extensions/gis/geographic/strategies/vincenty.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/extensions/gis/geographic/strategies/vincenty.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,151 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_EXTENSIONS_GIS_GEOGRAPHIC_STRATEGIES_VINCENTY_HPP
+#define GGL_EXTENSIONS_GIS_GEOGRAPHIC_STRATEGIES_VINCENTY_HPP
+
+
+#include <ggl/strategies/distance.hpp>
+#include <ggl/core/radian_access.hpp>
+#include <ggl/core/coordinate_type.hpp>
+
+#include <ggl/extensions/gis/geographic/detail/ellipsoid.hpp>
+
+
+namespace ggl
+{
+namespace strategy
+{
+
+    namespace distance
+    {
+
+        /*!
+            \brief Distance calculation formulae on latlong coordinates, after Vincenty, 1975
+            \ingroup distance
+            \tparam P1 first point type
+            \tparam P2 optional second point type
+            \author See http://www.ngs.noaa.gov/PUBS_LIB/inverse.pdf
+            \author Adapted from various implementations to get it close to the original document
+                - http://www.movable-type.co.uk/scripts/LatLongVincenty.html
+                - http://exogen.case.edu/projects/geopy/source/geopy.distance.html
+                - http://futureboy.homeip.net/fsp/colorize.fsp?fileName=navigation.frink
+
+        */
+        template <typename P1, typename P2 = P1>
+        class vincenty
+        {
+            public :
+                //typedef spherical_distance return_type;
+                typedef P1 first_point_type;
+                typedef P2 second_point_type;
+                typedef double return_type;
+
+                inline return_type apply(P1 const& p1, P2 const& p2) const
+                {
+                    return calculate(get_as_radian<0>(p1), get_as_radian<1>(p1),
+                                    get_as_radian<0>(p2), get_as_radian<1>(p2));
+                }
+
+            private :
+                typedef typename coordinate_type<P1>::type T1;
+                typedef typename coordinate_type<P2>::type T2;
+                ggl::detail::ellipsoid m_ellipsoid;
+
+                inline return_type calculate(T1 const& lon1, T1 const& lat1, T2 const& lon2, T2 const& lat2) const
+                {
+                    // lambda: difference in longitude on an auxiliary sphere
+                    double L = lon2 - lon1;
+                    double lambda = L;
+
+                    if (L < -math::pi) L += math::two_pi;
+                    if (L > math::pi) L -= math::two_pi;
+
+                    if (lat1 == lat2 && lon1 == lon2)
+                    {
+                      return return_type(0);
+                    }
+
+                    // U: reduced latitude, defined by tan U = (1-f) tan phi
+                    double U1 = atan((1-m_ellipsoid.f()) * tan(lat1)); // above (1)
+                    double U2 = atan((1-m_ellipsoid.f()) * tan(lat2)); // above (1)
+
+                    double cos_U1 = cos(U1);
+                    double cos_U2 = cos(U2);
+                    double sin_U1 = sin(U1);
+                    double sin_U2 = sin(U2);
+
+                    // alpha: azimuth of the geodesic at the equator
+                    double cos2_alpha;
+                    double sin_alpha;
+
+                    // sigma: angular distance p1,p2 on the sphere
+                    // sigma1: angular distance on the sphere from the equator to p1
+                    // sigma_m: angular distance on the sphere from the equator to the midpoint of the line
+                    double sigma;
+                    double sin_sigma;
+                    double cos2_sigma_m;
+
+                    double previous_lambda;
+
+                    do
+                    {
+                        previous_lambda = lambda; // (13)
+                        double sin_lambda = sin(lambda);
+                        double cos_lambda = cos(lambda);
+                        sin_sigma = sqrt(math::sqr(cos_U2 * sin_lambda) + math::sqr(cos_U1 * sin_U2 - sin_U1 * cos_U2 * cos_lambda)); // (14)
+                        double cos_sigma = sin_U1 * sin_U2 + cos_U1 * cos_U2 * cos_lambda; // (15)
+                        sin_alpha = cos_U1 * cos_U2 * sin_lambda / sin_sigma; // (17)
+                        cos2_alpha = 1.0 - math::sqr(sin_alpha);
+                        cos2_sigma_m = cos2_alpha == 0 ? 0 : cos_sigma - 2.0 * sin_U1 * sin_U2 / cos2_alpha; // (18)
+
+                        double C = m_ellipsoid.f()/16.0 * cos2_alpha * (4.0 + m_ellipsoid.f() * (4.0 - 3.0 * cos2_alpha)); // (10)
+                        sigma = atan2(sin_sigma, cos_sigma); // (16)
+                        lambda = L + (1.0 - C) * m_ellipsoid.f() * sin_alpha *
+                            (sigma + C * sin_sigma * ( cos2_sigma_m + C * cos_sigma * (-1.0 + 2.0 * math::sqr(cos2_sigma_m)))); // (11)
+
+                    } while (fabs(previous_lambda - lambda) > 1e-12 && fabs(lambda) < math::pi);
+
+                    double sqr_u = cos2_alpha * (math::sqr(m_ellipsoid.a()) - math::sqr(m_ellipsoid.b())) / math::sqr(m_ellipsoid.b()); // above (1)
+
+                    double A = 1.0 + sqr_u/16384.0 * (4096 + sqr_u * (-768.0 + sqr_u * (320.0 - 175.0 * sqr_u))); // (3)
+                    double B = sqr_u/1024.0 * (256.0 + sqr_u * ( -128.0 + sqr_u * (74.0 - 47.0 * sqr_u))); // (4)
+                    double delta_sigma = B * sin_sigma * ( cos2_sigma_m + (B/4.0) * (cos(sigma)* (-1.0 + 2.0 * cos2_sigma_m)
+                            - (B/6.0) * cos2_sigma_m * (-3.0 + 4.0 * math::sqr(sin_sigma)) * (-3.0 + 4.0 * cos2_sigma_m))); // (6)
+
+                    double dist = m_ellipsoid.b() * A * (sigma - delta_sigma); // (19)
+
+                    return return_type(dist);
+                }
+        };
+
+
+        // We might add a vincenty-like strategy also for point-segment distance, but to calculate the projected point is not trivial
+
+    } // namespace distance
+
+
+} // namespace strategy
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+template <typename P1, typename P2>
+struct strategy_tag<strategy::distance::vincenty<P1, P2> >
+{
+    typedef strategy_tag_distance_point_point type;
+};
+
+
+#endif
+
+
+} // namespace ggl
+
+
+#endif // GGL_EXTENSIONS_GIS_GEOGRAPHIC_STRATEGIES_VINCENTY_HPP
Added: sandbox/ggl/formal_review/boost/ggl/extensions/gis/io/wkb/detail/endian.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/extensions/gis/io/wkb/detail/endian.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,256 @@
+// Generic Geometry Library
+//
+// Copyright Mateusz Loskot <mateusz_at_[hidden]> 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// Load/Store values from/to stream of bytes across different endianness.
+//
+// Original design of unrolled_byte_loops templates based on
+// endian utility library from Boost C++ Libraries,
+// source: boost/spirit/home/support/detail/integer/endian.hpp
+// Copyright Darin Adler 2000
+// Copyright Beman Dawes 2006, 2009
+// Distributed under the Boost Software License, Version 1.0.
+
+#ifndef GGL_DETAIL_ENDIAN_HPP
+#define GGL_DETAIL_ENDIAN_HPP
+
+#include <cassert>
+#include <climits>
+#include <cstring>
+#include <cstddef>
+
+#include <boost/config.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/detail/endian.hpp>
+#include <boost/type_traits/is_signed.hpp>
+
+#if CHAR_BIT != 8
+#error Platforms with CHAR_BIT != 8 are not supported
+#endif
+
+// TODO: mloskot - add static asserts to validate compile-time pre-conditions
+
+namespace ggl { namespace detail { namespace endian {
+
+// Endianness tag used to indicate load/store directoin
+
+struct big_endian_tag {};
+struct little_endian_tag {};
+
+#ifdef BOOST_BIG_ENDIAN
+typedef big_endian_tag native_endian_tag;
+#else
+typedef little_endian_tag native_endian_tag;
+#endif
+
+// Unrolled loops for loading and storing streams of bytes.
+
+template <typename T, std::size_t N, bool Sign = boost::is_signed<T>::value>
+struct unrolled_byte_loops
+{
+    typedef unrolled_byte_loops<T, N - 1, Sign> next;
+
+    template <typename Iterator>
+    static T load_forward(Iterator& bytes)
+    {
+        T const value = *bytes;
+        ++bytes;
+        return value | (next::load_forward(bytes) << 8);
+    }
+
+    template <typename Iterator>
+    static T load_backward(Iterator& bytes)
+    {
+        T const value = *(bytes - 1);
+        --bytes;
+        return value | (next::load_backward(bytes) << 8);
+    }
+
+    template <typename Iterator>
+    static void store_forward(Iterator& bytes, T value)
+    {
+        *bytes = static_cast<char>(value);
+        next::store_forward(++bytes, value >> 8);
+    }
+
+    template <typename Iterator>
+    static void store_backward(Iterator& bytes, T value)
+    {
+        *(bytes - 1) = static_cast<char>(value);
+        next::store_backward(--bytes, value >> 8);
+    }
+};
+
+template <typename T>
+struct unrolled_byte_loops<T, 1, false>
+{
+    template <typename Iterator>
+    static T load_forward(Iterator& bytes)
+    {
+        return *bytes;
+    }
+
+    template <typename Iterator>
+    static T load_backward(Iterator& bytes)
+    {
+        return *(bytes - 1);
+    }
+
+    template <typename Iterator>
+    static void store_forward(Iterator& bytes, T value)
+    {
+        // typename Iterator::value_type
+        *bytes = static_cast<char>(value);
+    }
+
+    template <typename Iterator>
+    static void store_backward(Iterator& bytes, T value)
+    {
+        *(bytes - 1) = static_cast<char>(value);
+    }
+};
+
+template <typename T>
+struct unrolled_byte_loops<T, 1, true>
+{    
+    template <typename Iterator>
+    static T load_forward(Iterator& bytes)
+    {
+        return *reinterpret_cast<const signed char*>(&*bytes);
+    }
+
+    template <typename Iterator>
+    static T load_backward(Iterator& bytes)
+    {
+        return *reinterpret_cast<const signed char*>(&*(bytes - 1));
+    }
+    
+    template <typename Iterator>
+    static void store_forward(Iterator& bytes, T value)
+    {
+        BOOST_STATIC_ASSERT((boost::is_signed<typename Iterator::value_type>::value));
+
+        *bytes = static_cast<typename Iterator::value_type>(value);
+    }
+
+    template <typename Iterator>
+    static void store_backward(Iterator& bytes, T value)
+    {
+        BOOST_STATIC_ASSERT((boost::is_signed<typename Iterator::value_type>::value));
+
+        *(bytes - 1) = static_cast<typename Iterator::value_type>(value);
+    }
+};
+
+// load/store operation dispatch
+// E, E - source and target endianness is the same
+// E1, E2 - source and target endianness is different (big-endian <-> little-endian)
+
+template <typename T, std::size_t N, typename Iterator, typename E>
+T load_dispatch(Iterator& bytes, E, E)
+{
+    return unrolled_byte_loops<T, N>::load_forward(bytes);
+}
+
+template <typename T, std::size_t N, typename Iterator, typename E1, typename E2>
+T load_dispatch(Iterator& bytes, E1, E2)
+{
+    std::advance(bytes, N);
+    return unrolled_byte_loops<T, N>::load_backward(bytes);
+}
+
+template <typename T, std::size_t N, typename Iterator, typename E>
+void store_dispatch(Iterator& bytes, T value, E, E)
+{
+    return unrolled_byte_loops<T, N>::store_forward(bytes, value);
+}
+
+template <typename T, std::size_t N, typename Iterator, typename E1, typename E2>
+void store_dispatch(Iterator& bytes, T value, E1, E2)
+{
+    std::advance(bytes, N);
+    return unrolled_byte_loops<T, N>::store_backward(bytes, value);
+}
+
+// numeric value holder for load/store operation
+
+template <typename T>
+struct endian_value_base
+{
+    typedef T value_type;
+    typedef native_endian_tag endian_type;
+
+    endian_value_base() : value(T()) {}
+    explicit endian_value_base(T value) : value(value) {}
+
+    operator T() const
+    {
+        return value;
+    }
+
+protected:
+    T value;
+};
+
+template <typename T, std::size_t N = sizeof(T)>
+struct endian_value : public endian_value_base<T>
+{
+    typedef endian_value_base<T> base;
+
+    endian_value() {}
+    explicit endian_value(T value) : base(value) {}
+
+    template <typename E, typename Iterator>
+    void load(Iterator bytes)
+    {
+        base::value = load_dispatch<T, N>(bytes, typename base::endian_type(), E());
+    }
+
+    template <typename E, typename Iterator>
+    void store(Iterator bytes)
+    {
+        store_dispatch<T, N>(bytes, base::value, typename base::endian_type(), E());
+    }
+};
+
+template <>
+struct endian_value<double, 8> : public endian_value_base<double>
+{
+    typedef endian_value_base<double> base;
+
+    endian_value() {}
+    explicit endian_value(double value) : base(value) {}
+
+    template <typename E, typename Iterator>
+    void load(Iterator bytes)
+    {
+        endian_value<boost::uint64_t, 8> raw;
+        raw.load<E>(bytes);
+
+        double& target_value = base::value;
+        std::memcpy(&target_value, &raw, sizeof(double));
+    }
+
+    template <typename E, typename Iterator>
+    void store(Iterator bytes)
+    {
+        boost::uint64_t raw;
+        double const& source_value = base::value;
+        std::memcpy(&raw, &source_value, sizeof(boost::uint64_t));
+
+        store_dispatch
+            <
+            boost::uint64_t,
+            sizeof(boost::uint64_t)
+            >(bytes, raw, typename base::endian_type(), E());
+    }
+};
+
+}}} // namespace ggl::detail::endian
+
+#endif // GGL_DETAIL_ENDIAN_HPP
+
Added: sandbox/ggl/formal_review/boost/ggl/extensions/gis/io/wkb/detail/ogc.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/extensions/gis/io/wkb/detail/ogc.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,82 @@
+// Generic Geometry Library
+//
+// Copyright Mateusz Loskot <mateusz_at_[hidden]> 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_IO_WKB_DETAIL_OGC_HPP
+#define GGL_IO_WKB_DETAIL_OGC_HPP
+
+#include <boost/cstdint.hpp>
+
+namespace ggl
+{
+
+// The well-known binary representation for OGC geometry (WKBGeometry),
+// provides a portable representation of a geometry value as a contiguous
+// stream of bytes. It permits geometry values to be exchanged between
+// a client application and an SQL database in binary form.
+//
+// Basic Type definitions
+// byte : 1 byte
+// uint32 : 32 bit unsigned integer (4 bytes)
+// double : double precision number (8 bytes)
+//
+// enum wkbByteOrder
+// {
+//   wkbXDR = 0, // Big Endian
+//   wkbNDR = 1  // Little Endian
+// };
+//
+// enum wkbGeometryType
+// {
+//   wkbPoint = 1,
+//   wkbLineString = 2,
+//   wkbPolygon = 3,
+//   wkbMultiPoint = 4,
+//   wkbMultiLineString = 5,
+//   wkbMultiPolygon = 6,
+//   wkbGeometryCollection = 7
+// };
+
+#ifndef DOXYGEN_NO_IMPL
+namespace detail { namespace wkb {
+
+// TODO: Replace 'struct' with scoped enum from <boost/detail/scoped_enum_emulation.hpp>
+// For older Boost, copy
+// <boost/spirit/home/support/detail/scoped_enum_emulation.hpp>
+// to
+// <boost/ggl/detail/scoped_enum_emulation.hpp>
+// and use it.
+
+struct byte_order_type
+{
+    enum enum_t
+    {
+        xdr     = 0, // wkbXDR, bit-endian
+        ndr     = 1, // wkbNDR, little-endian
+        unknown = 2  // not defined by OGC
+    };
+};
+
+struct geometry_type
+{
+    enum enum_t
+    {
+        point      = 1,
+        linestring = 2,
+        polygon    = 3
+
+        // TODO: Not implemented
+        //multipoint = 4,
+        //multilinestring = 5,
+        //multipolygon = 6,
+        //collection = 7
+    };
+};
+
+}}} // namespace ggl::detail::wkb
+#endif // DOXYGEN_NO_IMPL
+
+#endif // GGL_IO_WKB_DETAIL_OGC_HPP
Added: sandbox/ggl/formal_review/boost/ggl/extensions/gis/io/wkb/detail/parser.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/extensions/gis/io/wkb/detail/parser.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,305 @@
+// Generic Geometry Library
+//
+// Copyright Mateusz Loskot <mateusz_at_[hidden]> 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_IO_WKB_DETAIL_PARSER_HPP
+#define GGL_IO_WKB_DETAIL_PARSER_HPP
+
+#include <cassert>
+#include <cstddef>
+#include <algorithm>
+#include <iterator>
+#include <limits>
+
+#include <boost/cstdint.hpp>
+#include <boost/type_traits/is_integral.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/static_assert.hpp>
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/coordinate_dimension.hpp>
+#include <ggl/core/coordinate_type.hpp>
+#include <ggl/core/exterior_ring.hpp>
+#include <ggl/core/interior_rings.hpp>
+#include <ggl/extensions/gis/io/wkb/detail/endian.hpp>
+#include <ggl/extensions/gis/io/wkb/detail/ogc.hpp>
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_IMPL
+namespace detail { namespace wkb {
+
+template <typename T>
+struct value_parser
+{
+    typedef T value_type;
+
+    template <typename Iterator>
+    static bool parse(Iterator& it, Iterator end, T& value, byte_order_type::enum_t order)
+    {
+        // Very basic pre-conditions check on stream of bytes passed in
+        BOOST_STATIC_ASSERT((
+            boost::is_integral<typename std::iterator_traits<Iterator>::value_type>::value
+        ));
+        BOOST_STATIC_ASSERT((sizeof(boost::uint8_t) ==
+            sizeof(typename std::iterator_traits<Iterator>::value_type)
+        ));
+
+        typedef typename std::iterator_traits<Iterator>::difference_type diff_type;
+        diff_type const required_size = sizeof(T);
+        if (it != end && std::distance(it, end) >= required_size)
+        {
+            typedef endian::endian_value<T> parsed_value_type;
+            parsed_value_type parsed_value;
+
+            // Decide on direcion of endianness translation, detault to native
+            if (byte_order_type::xdr == order)
+            {
+                parsed_value.template load<endian::big_endian_tag>(it);
+            }
+            else if (byte_order_type::ndr == order)
+            {
+                parsed_value.template load<endian::little_endian_tag>(it);
+            }
+            else
+            {
+                parsed_value.template load<endian::native_endian_tag>(it);
+            }
+
+            value = parsed_value;
+            std::advance(it, required_size);
+            return true;
+        }
+
+        return false;
+    }
+};
+
+struct byte_order_parser
+{
+    template <typename Iterator>
+    static bool parse(Iterator& it, Iterator end, byte_order_type::enum_t& order)
+    {
+        boost::uint8_t value;
+        if (value_parser<boost::uint8_t>::parse(it, end, value, byte_order_type::unknown))
+        {
+            if (byte_order_type::unknown > value)
+            {
+                order = byte_order_type::enum_t(value);
+            }
+            return true;
+        }
+        return false;
+    }
+};
+
+struct geometry_type_parser
+{
+    template <typename Iterator>
+    static bool parse(Iterator& it, Iterator end, geometry_type::enum_t& type,
+        byte_order_type::enum_t order)
+    {
+        boost::uint32_t value;
+        if (value_parser<boost::uint32_t>::parse(it, end, value, order))
+        {
+            // TODO: Refine the test when multi* geometries are supported
+
+            boost::uint32_t id = value & 0xff;
+            if (geometry_type::polygon >= id)
+            {
+                type = geometry_type::enum_t(id);
+                return true;
+            }
+        }
+        return false;
+    }
+};
+
+template <typename P, int I, int N>
+struct parsing_assigner
+{
+    template <typename Iterator>
+    static void run(Iterator& it, Iterator end, P& point, byte_order_type::enum_t order)
+    {
+        typedef typename coordinate_type<P>::type coordinate_type;
+
+        // coordinate type in WKB is always double
+        double value(0);
+        if (value_parser<double>::parse(it, end, value, order))
+        {
+            // actual coordinate type of point may be different
+            set<I>(point, static_cast<coordinate_type>(value));
+        }
+        else
+        {
+            // TODO: mloskot - Report premature termination at coordinate level
+            //throw failed to read coordinate value
+
+            // default initialized value as fallback
+            set<I>(point, coordinate_type());
+        }
+        parsing_assigner<P, I+1, N>::run(it, end, point, order);
+    }
+};
+
+template <typename P, int N>
+struct parsing_assigner<P, N, N>
+{
+    template <typename Iterator>
+    static void run(Iterator& it, Iterator end, P& point, byte_order_type::enum_t order)
+    {
+        // terminate
+    }
+};
+
+template <typename P>
+struct point_parser
+{
+    template <typename Iterator>
+    static bool parse(Iterator& it, Iterator end, P& point, byte_order_type::enum_t order)
+    {
+        // TODO: mloskot - Add assert on point dimension, 2d only
+
+        geometry_type::enum_t type;
+        if (geometry_type_parser::parse(it, end, type, order))
+        {
+            if (geometry_type::point == type && it != end)
+            {
+                parsing_assigner<P, 0, dimension<P>::value>::run(it, end, point, order);
+            }
+            return true;
+        }
+        return false;
+    }
+};
+
+template <typename C>
+struct point_container_parser
+{
+    template <typename Iterator>
+    static bool parse(Iterator& it, Iterator end, C& container, byte_order_type::enum_t order)
+    {
+        typedef typename point_type<C>::type point_type;
+
+        boost::uint32_t num_points(0);
+        if (!value_parser<boost::uint32_t>::parse(it, end, num_points, order))
+        {
+            return false;
+        }
+
+        typedef typename std::iterator_traits<Iterator>::difference_type size_type;
+        assert(num_points <= boost::uint32_t( (std::numeric_limits<size_type>::max)() ) );
+
+        size_type const container_size = static_cast<size_type>(num_points);
+        size_type const point_size = dimension<point_type>::value * sizeof(double);
+
+        if (std::distance(it, end) >= (container_size * point_size))
+        {
+            point_type point_buffer;
+            std::back_insert_iterator<C> output(std::back_inserter(container));
+
+            // Read coordinates into point and append point to line (ring)
+            size_type points_parsed = 0;
+            while (points_parsed < container_size && it != end)
+            {
+                parsing_assigner<point_type, 0, dimension<point_type>::value>::run(it, end, point_buffer, order);
+                output = point_buffer;
+                ++output;
+                ++points_parsed;
+            }
+
+            if (container_size != points_parsed)
+            {
+                return false;
+            }
+        }
+
+        return true;
+    }
+};
+
+template <typename L>
+struct linestring_parser
+{
+    template <typename Iterator>
+    static bool parse(Iterator& it, Iterator end, L& linestring, byte_order_type::enum_t order)
+    {
+        typedef typename point_type<L>::type point_type;
+
+        geometry_type::enum_t type;
+        if (!geometry_type_parser::parse(it, end, type, order))
+        {
+            return false;
+        }
+
+        if (geometry_type::linestring != type)
+        {
+            return false;
+        }
+
+        assert(it != end);
+        return point_container_parser<L>::parse(it, end, linestring, order);
+    }
+};
+
+template <typename Polygon>
+struct polygon_parser
+{
+    template <typename Iterator>
+    static bool parse(Iterator& it, Iterator end, Polygon& polygon, byte_order_type::enum_t order)
+    {
+        geometry_type::enum_t type;
+        if (!geometry_type_parser::parse(it, end, type, order))
+        {
+            return false;
+        }
+
+        boost::uint32_t num_rings(0);
+        if (geometry_type::polygon != type ||
+            !value_parser<boost::uint32_t>::parse(it, end, num_rings, order))
+        {
+            return false;
+        }
+
+        typedef typename ring_type<Polygon>::type ring_type;
+
+        std::size_t rings_parsed = 0;
+        while (rings_parsed < num_rings && it != end) //while (rings_parsed < num_rings && it != end)
+        {
+            if (0 == rings_parsed)
+            {
+                ring_type& ring0 = exterior_ring(polygon);
+                if (!point_container_parser<ring_type>::parse(it, end, ring0, order))
+                {
+                    return false;
+                }
+            }
+            else
+            {
+                interior_rings(polygon).resize(rings_parsed);
+                ring_type& ringN = interior_rings(polygon).back();
+                if (!point_container_parser<ring_type>::parse(it, end, ringN, order))
+                {
+                    return false;
+                }
+            }
+            ++rings_parsed;
+        }
+
+        if (num_rings != rings_parsed)
+        {
+            return false;
+        }
+
+        return true;
+    }
+};
+
+}}} // namespace ggl::detail::wkb
+#endif // DOXYGEN_NO_IMPL
+
+#endif // GGL_IO_WKB_DETAIL_PARSER_HPP
Added: sandbox/ggl/formal_review/boost/ggl/extensions/gis/io/wkb/read_wkb.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/extensions/gis/io/wkb/read_wkb.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,107 @@
+// Generic Geometry Library
+//
+// Copyright Mateusz Loskot <mateusz_at_[hidden]> 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_IO_WKB_READ_WKB_HPP
+#define GGL_IO_WKB_READ_WKB_HPP
+
+#include <iterator>
+
+#include <boost/type_traits/is_convertible.hpp>
+#include <boost/static_assert.hpp>
+
+#include <ggl/core/tags.hpp>
+#include <ggl/extensions/gis/io/wkb/detail/parser.hpp>
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Tag, typename G>
+struct read_wkb {};
+
+template <typename G>
+struct read_wkb<point_tag, G>
+{
+    template <typename Iterator>
+    static inline bool parse(Iterator& it, Iterator end, G& geometry,
+        detail::wkb::byte_order_type::enum_t order)
+    {
+        return detail::wkb::point_parser<G>::parse(it, end, geometry, order);
+    }
+};
+
+template <typename G>
+struct read_wkb<linestring_tag, G>
+{
+    template <typename Iterator>
+    static inline bool parse(Iterator& it, Iterator end, G& geometry,
+        detail::wkb::byte_order_type::enum_t order)
+    {
+        ggl::clear(geometry);
+        return detail::wkb::linestring_parser<G>::parse(it, end, geometry, order);
+    }
+};
+
+template <typename G>
+struct read_wkb<polygon_tag, G>
+{
+    template <typename Iterator>
+    static inline bool parse(Iterator& it, Iterator end, G& geometry,
+        detail::wkb::byte_order_type::enum_t order)
+    {
+        ggl::clear(geometry);
+        return detail::wkb::polygon_parser<G>::parse(it, end, geometry, order);
+    }
+};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+template <typename Iterator, typename G>
+inline bool read_wkb(Iterator begin, Iterator end, G& geometry)
+{
+    // Stream of bytes can only be parsed using random access iterator.
+    BOOST_STATIC_ASSERT((
+        boost::is_convertible
+        <
+            typename std::iterator_traits<Iterator>::iterator_category,
+            const std::random_access_iterator_tag&
+        >::value));
+
+    detail::wkb::byte_order_type::enum_t byte_order;
+    if (detail::wkb::byte_order_parser::parse(begin, end, byte_order))
+    {
+        return dispatch::read_wkb
+            <
+            typename tag<G>::type,
+            G
+            >::parse(begin, end, geometry, byte_order);
+    }
+
+    return false;
+}
+
+template <typename ByteType, typename G>
+inline bool read_wkb(ByteType const* bytes, std::size_t length, G& geometry)
+{
+    BOOST_STATIC_ASSERT((boost::is_integral<ByteType>::value));
+    BOOST_STATIC_ASSERT((sizeof(boost::uint8_t) == sizeof(ByteType)));
+
+    ByteType const* begin = bytes;
+    ByteType const* const end = bytes + length;
+
+    return read_wkb(begin, end, geometry);
+}
+
+
+} // namespace ggl
+
+#endif // GGL_IO_WKB_READ_WKB_HPP
Added: sandbox/ggl/formal_review/boost/ggl/extensions/gis/io/wkb/utility.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/extensions/gis/io/wkb/utility.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,89 @@
+// Generic Geometry Library
+//
+// Copyright Mateusz Loskot <mateusz_at_[hidden]> 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_IO_WKB_UTILITY_HPP
+#define GGL_IO_WKB_UTILITY_HPP
+
+#include <iomanip>
+#include <iterator>
+#include <sstream>
+#include <string>
+
+#include <boost/cstdint.hpp>
+
+namespace ggl {
+
+// TODO: Waiting for errors handling design, eventually return bool
+// may be replaced to throw exception.
+
+template <typename OutputIterator>
+bool hex2wkb(std::string const& hex, OutputIterator bytes)
+{
+    // Bytes can be only written to output iterator.
+    BOOST_STATIC_ASSERT((boost::is_convertible<
+        typename std::iterator_traits<OutputIterator>::iterator_category,
+        const std::output_iterator_tag&>::value));
+
+    std::string::size_type const byte_size = 2;
+    if (0 != hex.size() % byte_size)
+    {
+        return false;
+    }
+
+    std::string::size_type const size = hex.size() / byte_size;
+    for (std::string::size_type i = 0; i < size; ++i)
+    {
+        // TODO: This is confirmed performance killer - to be replaced with static char-to-byte map --mloskot
+        std::istringstream iss(hex.substr(i * byte_size, byte_size));
+        unsigned int byte(0);
+        if (!(iss >> std::hex >> byte))
+        {
+            return false;
+        }
+        *bytes = static_cast<boost::uint8_t>(byte);
+        ++bytes;
+    }
+
+    return true;
+}
+
+template <typename Iterator>
+bool wkb2hex(Iterator begin, Iterator end, std::string& hex)
+{
+    // Stream of bytes can only be passed using random access iterator.
+    BOOST_STATIC_ASSERT((boost::is_convertible<
+        typename std::iterator_traits<Iterator>::iterator_category,
+        const std::random_access_iterator_tag&>::value));
+
+    const char hexalpha[] = "0123456789ABCDEF";
+    char hexbyte[3] = { 0 };
+    std::ostringstream oss;
+
+    Iterator it = begin;
+    while (it != end)
+    {
+        boost::uint8_t byte = static_cast<boost::uint8_t>(*it);
+        hexbyte[0] = hexalpha[(byte >> 4) & 0xf];
+        hexbyte[1] = hexalpha[byte & 0xf];
+        hexbyte[2] = '\0';
+        oss << std::setw(2) << hexbyte;
+        ++it;
+    }
+
+    // TODO: Binary streams can be big.
+    // Does it make sense to request stream buffer of proper (large) size or
+    // use incremental appends within while-loop?
+    hex = oss.str();
+
+    // Poor-man validation, no performance penalty expected
+    // because begin/end always are random access iterators.
+    return hex.size() == (2 * std::distance(begin, end));
+}
+
+} // namespace ggl
+
+#endif // GGL_IO_WKB_UTILITY_HPP
Added: sandbox/ggl/formal_review/boost/ggl/extensions/gis/io/wkt/detail/wkt.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/extensions/gis/io/wkt/detail/wkt.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,45 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 2008-2009, Geodan, Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_IO_WKT_DETAIL_WKT_HPP
+#define GGL_IO_WKT_DETAIL_WKT_HPP
+
+
+
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace wkt {
+
+
+struct prefix_point
+{
+    static inline const char* apply() { return "POINT"; }
+};
+
+struct prefix_polygon
+{
+    static inline const char* apply() { return "POLYGON"; }
+};
+
+struct prefix_linestring
+{
+    static inline const char* apply() { return "LINESTRING"; }
+};
+
+
+
+}} // namespace wkt::impl
+#endif
+
+
+
+} // namescpae ggl
+
+#endif // GGL_IO_WKT_DETAIL_WKT_HPP
Added: sandbox/ggl/formal_review/boost/ggl/extensions/gis/io/wkt/detail/wkt_multi.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/extensions/gis/io/wkt/detail/wkt_multi.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,51 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 2008-2009, Geodan, Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_IO_WKT_DETAIL_WKT_HPP
+#define GGL_MULTI_IO_WKT_DETAIL_WKT_HPP
+
+
+#include <ggl/extensions/gis/io/wkt/write_wkt.hpp>
+#include <ggl/multi/core/tags.hpp>
+
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace wkt {
+
+struct prefix_null
+{
+    static inline const char* apply() { return ""; }
+};
+
+struct prefix_multipoint
+{
+    static inline const char* apply() { return "MULTIPOINT"; }
+};
+
+struct prefix_multilinestring
+{
+    static inline const char* apply() { return "MULTILINESTRING"; }
+};
+
+struct prefix_multipolygon
+{
+    static inline const char* apply() { return "MULTIPOLYGON"; }
+};
+
+
+
+}} // namespace wkt::impl
+#endif
+
+
+
+} // namescpae ggl
+
+#endif // GGL_MULTI_IO_WKT_DETAIL_WKT_HPP
Added: sandbox/ggl/formal_review/boost/ggl/extensions/gis/io/wkt/read_wkt.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/extensions/gis/io/wkt/read_wkt.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,681 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 2008-2009, Geodan, Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_EXTENSIONS_GIS_IO_WKT_READ_WKT_HPP
+#define GGL_EXTENSIONS_GIS_IO_WKT_READ_WKT_HPP
+
+#include <string>
+
+#include <boost/lexical_cast.hpp>
+#include <boost/tokenizer.hpp>
+
+#include <boost/algorithm/string.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <boost/type_traits.hpp>
+
+
+#include <ggl/algorithms/assign.hpp>
+#include <ggl/algorithms/clear.hpp>
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/coordinate_dimension.hpp>
+#include <ggl/core/exception.hpp>
+#include <ggl/core/exterior_ring.hpp>
+#include <ggl/core/interior_rings.hpp>
+
+#include <ggl/geometries/concepts/check.hpp>
+
+
+#include <ggl/extensions/gis/io/wkt/detail/wkt.hpp>
+
+namespace ggl
+{
+
+
+
+/*!
+\brief Exception showing things wrong with WKT parsing
+\ingroup wkt
+*/
+struct read_wkt_exception : public ggl::exception
+{
+    template <typename Iterator>
+    read_wkt_exception(std::string const& msg,
+            Iterator const& it, Iterator const& end, std::string const& wkt)
+        : message(msg)
+        , wkt(wkt)
+    {
+        if (it != end)
+        {
+            source = " at '";
+            source += it->c_str();
+            source += "'";
+        }
+        complete = message + source + " in '" + wkt.substr(0, 100) + "'";
+    }
+
+    read_wkt_exception(std::string const& msg, std::string const& wkt)
+        : message(msg)
+        , wkt(wkt)
+    {
+        complete = message + "' in (" + wkt.substr(0, 100) + ")";
+    }
+
+    virtual ~read_wkt_exception() throw() {}
+
+    virtual const char* what() const throw()
+    {
+        return complete.c_str();
+    }
+private :
+    std::string source;
+    std::string message;
+    std::string wkt;
+    std::string complete;
+};
+
+
+
+#ifndef DOXYGEN_NO_DETAIL
+// (wkt: Well Known Text, defined by OGC for all geometries and implemented by e.g. databases (MySQL, PostGIS))
+namespace detail { namespace wkt {
+
+typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
+
+template <typename Point, std::size_t Dimension, std::size_t DimensionCount>
+struct parsing_assigner
+{
+    static inline void apply(tokenizer::iterator& it, tokenizer::iterator end,
+            Point& point, std::string const& wkt)
+    {
+        typedef typename coordinate_type<Point>::type coordinate_type;
+        typedef typename boost::mpl::if_c
+            <
+                boost::is_fundamental<coordinate_type>::type::value,
+                coordinate_type,
+                double
+            >::type type;
+
+
+
+        // Stop at end of tokens, or at "," ot ")"
+        bool finished = (it == end || *it == "," || *it == ")");
+
+        try
+        {
+            // Initialize missing coordinates to default constructor (zero)
+            // OR
+            // Use lexical_cast for conversion to double/int
+            // Note that it is much slower than atof. However, it is more standard
+            // and in parsing the change in performance falls probably away against
+            // the tokenizing
+            set<Dimension>(point, (finished ? type() : boost::lexical_cast<type>(it->c_str())));
+        }
+        catch(boost::bad_lexical_cast const& blc)
+        {
+            throw read_wkt_exception(blc.what(), it, end, wkt);
+        }
+        catch(std::exception const& e)
+        {
+            throw read_wkt_exception(e.what(), it, end, wkt);
+        }
+        catch(...)
+        {
+            throw read_wkt_exception("", it, end, wkt);
+        }
+
+        parsing_assigner<Point, Dimension + 1, DimensionCount>::apply(
+                        (finished ? it : ++it), end, point, wkt);
+    }
+};
+
+template <typename Point, std::size_t DimensionCount>
+struct parsing_assigner<Point, DimensionCount, DimensionCount>
+{
+    static inline void apply(tokenizer::iterator&, tokenizer::iterator, Point&,
+                std::string const&)
+    {
+    }
+};
+
+
+
+template <typename Iterator>
+inline void handle_open_parenthesis(Iterator& it,
+            Iterator const& end, std::string const& wkt)
+{
+    if (it == end || *it != "(")
+    {
+        throw read_wkt_exception("Expected '('", it, end, wkt);
+    }
+    ++it;
+}
+
+
+template <typename Iterator>
+inline void handle_close_parenthesis(Iterator& it,
+            Iterator const& end, std::string const& wkt)
+{
+    if (it != end && *it == ")")
+    {
+        ++it;
+    }
+    else
+    {
+        throw read_wkt_exception("Expected ')'", it, end, wkt);
+    }
+}
+
+template <typename Iterator>
+inline void check_end(Iterator& it,
+            Iterator const& end, std::string const& wkt)
+{
+    if (it != end)
+    {
+        throw read_wkt_exception("Too much tokens", it, end, wkt);
+    }
+}
+
+/*!
+\brief Internal, parses coordinate sequences, strings are formated like "(1 2,3 4,...)"
+\param it token-iterator, should be pre-positioned at "(", is post-positions after last ")"
+\param end end-token-iterator
+\param out Output itererator receiving coordinates
+*/
+template <typename Point>
+struct container_inserter
+{
+    // Version with output iterator
+    template <typename OutputIterator>
+    static inline void apply(tokenizer::iterator& it, tokenizer::iterator end,
+        std::string const& wkt, OutputIterator out)
+    {
+        handle_open_parenthesis(it, end, wkt);
+
+        Point point;
+
+        // Parse points until closing parenthesis
+
+        while (it != end && *it != ")")
+        {
+            parsing_assigner
+                <
+                    Point,
+                    0,
+                    dimension<Point>::value
+                >::apply(it, end, point, wkt);
+            out = point;
+            ++out;
+            if (it != end && *it == ",")
+            {
+                ++it;
+            }
+        }
+
+        handle_close_parenthesis(it, end, wkt);
+    }
+};
+
+/*!
+\brief Internal, parses a point from a string like this "(x y)"
+\note used for parsing points and multi-points
+*/
+template <typename P>
+struct point_parser
+{
+    static inline void apply(tokenizer::iterator& it, tokenizer::iterator end,
+        std::string const& wkt, P& point)
+    {
+        handle_open_parenthesis(it, end, wkt);
+        parsing_assigner<P, 0, dimension<P>::value>::apply(it, end, point, wkt);
+        handle_close_parenthesis(it, end, wkt);
+    }
+};
+
+
+template <typename Geometry>
+struct linestring_parser
+{
+    static inline void apply(tokenizer::iterator& it, tokenizer::iterator end,
+                std::string const& wkt, Geometry& geometry)
+    {
+        container_inserter
+            <
+                typename point_type<Geometry>::type
+            >::apply(it, end, wkt, std::back_inserter(geometry));
+    }
+};
+
+
+template <typename Ring>
+struct ring_parser
+{
+    static inline void apply(tokenizer::iterator& it, tokenizer::iterator end,
+                std::string const& wkt, Ring& ring)
+    {
+        // A ring should look like polygon((x y,x y,x y...))
+        // So handle the extra opening/closing parentheses
+        // and in between parse using the container-inserter
+        handle_open_parenthesis(it, end, wkt);
+        container_inserter
+            <
+                typename point_type<Ring>::type
+            >::apply(it, end, wkt, std::back_inserter(ring));
+        handle_close_parenthesis(it, end, wkt);
+    }
+};
+
+
+
+
+/*!
+\brief Internal, parses a polygon from a string like this "((x y,x y),(x y,x y))"
+\note used for parsing polygons and multi-polygons
+*/
+template <typename Polygon>
+struct polygon_parser
+{
+    static inline void apply(tokenizer::iterator& it, tokenizer::iterator end,
+                std::string const& wkt, Polygon& poly)
+    {
+        typedef container_inserter
+            <
+                typename point_type<Polygon>::type
+            > container_inserter;
+
+        handle_open_parenthesis(it, end, wkt);
+
+        int n = -1;
+
+        // Stop at ")"
+        while (it != end && *it != ")")
+        {
+            // Parse ring
+            if (++n == 0)
+            {
+                container_inserter::apply(it, end, wkt,
+                        std::back_inserter(exterior_ring(poly)));
+            }
+            else
+            {
+                interior_rings(poly).resize(n);
+                container_inserter::apply(it, end, wkt,
+                        std::back_inserter(interior_rings(poly).back()));
+            }
+
+            if (it != end && *it == ",")
+            {
+                // Skip "," after ring is parsed
+                ++it;
+            }
+        }
+
+        handle_close_parenthesis(it, end, wkt);
+    }
+};
+
+inline bool one_of(tokenizer::iterator const& it, std::string const& value,
+            bool& is_present)
+{
+    if (boost::iequals(*it, value))
+    {
+        is_present = true;
+        return true;
+    }
+    return false;
+}
+
+inline bool one_of(tokenizer::iterator const& it, std::string const& value,
+            bool& present1, bool& present2)
+{
+    if (boost::iequals(*it, value))
+    {
+        present1 = true;
+        present2 = true;
+        return true;
+    }
+    return false;
+}
+
+
+inline void handle_empty_z_m(tokenizer::iterator& it, tokenizer::iterator end,
+            bool& has_empty, bool& has_z, bool& has_m)
+{
+    has_empty = false;
+    has_z = false;
+    has_m = false;
+
+    // WKT can optionally have Z and M (measured) values as in
+    // POINT ZM (1 1 5 60), POINT M (1 1 80), POINT Z (1 1 5)
+    // GGL supports any of them as coordinate values, but is not aware
+    // of any Measured value.
+    while (it != end
+           && (one_of(it, "M", has_m)
+               || one_of(it, "Z", has_z)
+               || one_of(it, "EMPTY", has_empty)
+               || one_of(it, "MZ", has_m, has_z)
+               || one_of(it, "ZM", has_z, has_m)
+               )
+           )
+    {
+        ++it;
+    }
+}
+
+/*!
+\brief Internal, starts parsing
+\param tokens boost tokens, parsed with separator " " and keeping separator "()"
+\param geometry string to compare with first token
+*/
+template <typename Geometry>
+inline bool initialize(tokenizer const& tokens,
+            std::string const& geometry_name, std::string const& wkt,
+            tokenizer::iterator& it)
+{
+    it = tokens.begin();
+    if (it != tokens.end() && boost::iequals(*it++, geometry_name))
+    {
+        bool has_empty, has_z, has_m;
+
+        handle_empty_z_m(it, tokens.end(), has_empty, has_z, has_m);
+
+        if (has_z && dimension<Geometry>::type::value < 3)
+        {
+            throw read_wkt_exception("Z only allowed for 3 or more dimensions", wkt);
+        }
+        if (has_empty)
+        {
+            check_end(it, tokens.end(), wkt);
+            return false;
+        }
+        // M is ignored at all.
+
+        return true;
+    }
+    throw read_wkt_exception(std::string("Should start with '") + geometry_name + "'", wkt);
+}
+
+
+template <typename Geometry, template<typename> class Parser, typename PrefixPolicy>
+struct geometry_parser
+{
+    static inline void apply(std::string const& wkt, Geometry& geometry)
+    {
+        ggl::clear(geometry);
+
+        tokenizer tokens(wkt, boost::char_separator<char>(" ", ",()"));
+        tokenizer::iterator it;
+        if (initialize<Geometry>(tokens, PrefixPolicy::apply(), wkt, it))
+        {
+            Parser<Geometry>::apply(it, tokens.end(), wkt, geometry);
+            check_end(it, tokens.end(), wkt);
+        }
+    }
+};
+
+
+
+
+
+/*!
+\brief Supports box parsing
+\note OGC does not define the box geometry, and WKT does not support boxes.
+    However, to be generic GGL supports reading and writing from and to boxes.
+    Boxes are outputted as a standard POLYGON. GGL can read boxes from
+    a standard POLYGON, from a POLYGON with 2 points of from a BOX
+\tparam Box the box
+*/
+template <typename Box>
+struct box_parser
+{
+    static inline void apply(std::string const& wkt, Box& box)
+    {
+        bool should_close = false;
+        tokenizer tokens(wkt, boost::char_separator<char>(" ", ",()"));
+        tokenizer::iterator it = tokens.begin();
+        tokenizer::iterator end = tokens.end();
+        if (it != end && boost::iequals(*it, "POLYGON"))
+        {
+            ++it;
+            bool has_empty, has_z, has_m;
+            handle_empty_z_m(it, end, has_empty, has_z, has_m);
+            if (has_empty)
+            {
+                assign_zero(box);
+                return;
+            }
+            handle_open_parenthesis(it, end, wkt);
+            should_close = true;
+        }
+        else if (it != end && boost::iequals(*it, "BOX"))
+        {
+            ++it;
+        }
+        else
+        {
+            throw read_wkt_exception("Should start with 'POLYGON' or 'BOX'", wkt);
+        }
+
+        typedef typename point_type<Box>::type point_type;
+        std::vector<point_type> points;
+        container_inserter<point_type>::apply(it, end, wkt, std::back_inserter(points));
+
+        if (should_close)
+        {
+            handle_close_parenthesis(it, end, wkt);
+        }
+        check_end(it, end, wkt);
+
+        int index = 0;
+        int n = boost::size(points);
+        if (n == 2)
+        {
+            index = 1;
+        }
+        else if (n == 4 || n == 5)
+        {
+            // In case of 4 or 5 points, we do not check the other ones, just
+            // take the opposite corner which is always 2
+            index = 2;
+        }
+        else
+        {
+            throw read_wkt_exception("Box should have 2,4 or 5 points", wkt);
+        }
+
+        assign_point_to_index<min_corner>(points.front(), box);
+        assign_point_to_index<max_corner>(points[index], box);
+    }
+};
+
+
+/*!
+\brief Supports segment parsing
+\note OGC does not define the segment, and WKT does not support segmentes.
+    However, it is useful to implement it, also for testing purposes
+\tparam Segment the segment
+*/
+template <typename Segment>
+struct segment_parser
+{
+    static inline void apply(std::string const& wkt, Segment& segment)
+    {
+        tokenizer tokens(wkt, boost::char_separator<char>(" ", ",()"));
+        tokenizer::iterator it = tokens.begin();
+        tokenizer::iterator end = tokens.end();
+        if (it != end &&
+            (boost::iequals(*it, "SEGMENT")
+            || boost::iequals(*it, "LINESTRING") ))
+        {
+            ++it;
+        }
+        else
+        {
+            throw read_wkt_exception("Should start with 'LINESTRING' or 'SEGMENT'", wkt);
+        }
+
+        typedef typename point_type<Segment>::type point_type;
+        std::vector<point_type> points;
+        container_inserter<point_type>::apply(it, end, wkt, std::back_inserter(points));
+
+        check_end(it, end, wkt);
+
+        if (boost::size(points) == 2)
+        {
+            assign_point_to_index<0>(points.front(), segment);
+            assign_point_to_index<1>(points.back(), segment);
+        }
+        else
+        {
+            throw read_wkt_exception("Segment should have 2 points", wkt);
+        }
+
+    }
+};
+
+
+
+}} // namespace detail::wkt
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Tag, typename Geometry>
+struct read_wkt {};
+
+
+template <typename Point>
+struct read_wkt<point_tag, Point>
+    : detail::wkt::geometry_parser
+        <
+            Point,
+            detail::wkt::point_parser,
+            detail::wkt::prefix_point
+        >
+{};
+
+
+template <typename L>
+struct read_wkt<linestring_tag, L>
+    : detail::wkt::geometry_parser
+        <
+            L,
+            detail::wkt::linestring_parser,
+            detail::wkt::prefix_linestring
+        >
+{};
+
+template <typename Ring>
+struct read_wkt<ring_tag, Ring>
+    : detail::wkt::geometry_parser
+        <
+            Ring,
+            detail::wkt::ring_parser,
+            detail::wkt::prefix_polygon
+        >
+{};
+
+template <typename Geometry>
+struct read_wkt<polygon_tag, Geometry>
+    : detail::wkt::geometry_parser
+        <
+            Geometry,
+            detail::wkt::polygon_parser,
+            detail::wkt::prefix_polygon
+        >
+{};
+
+
+// Box (Non-OGC)
+template <typename Box>
+struct read_wkt<box_tag, Box>
+    : detail::wkt::box_parser<Box>
+{};
+
+// Segment (Non-OGC)
+template <typename Segment>
+struct read_wkt<segment_tag, Segment>
+    : detail::wkt::segment_parser<Segment>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+\brief Parses OGC Well-Known Text (\ref WKT) into a geometry (any geometry)
+\ingroup wkt
+\param wkt string containing \ref WKT
+\param geometry output geometry
+\par Example:
+\note It is case insensitive and can have the WKT forms "point", "point m", "point z", "point zm", "point mz"
+\note Empty sequences can have forms as "LINESTRING ()" or "POLYGON(())"
+Small example showing how to use read_wkt to build a point
+\dontinclude doxygen_1.cpp
+\skip example_from_wkt_point
+\line {
+\until }
+\par Example:
+Small example showing how to use read_wkt to build a linestring
+\dontinclude doxygen_1.cpp
+\skip example_from_wkt_linestring
+\line {
+\until }
+\par Example:
+Small example showing how to use read_wkt to build a polygon
+\dontinclude doxygen_1.cpp
+\skip example_from_wkt_polygon
+\line {
+\until }
+*/
+template <typename Geometry>
+inline void read_wkt(std::string const& wkt, Geometry& geometry)
+{
+    ggl::concept::check<Geometry>();
+    dispatch::read_wkt<typename tag<Geometry>::type, Geometry>::apply(wkt, geometry);
+}
+
+/*!
+\brief Parses OGC Well-Known Text (\ref WKT) and outputs using an output iterator
+\ingroup wkt
+\param wkt string containing \ref WKT
+\param out output iterator
+\note Because the output iterator doesn't always have the type value_type, it should be
+specified in the function call.
+\par Example:
+Small example showing how to use read_wkt with an output iterator
+\dontinclude doxygen_1.cpp
+\skip example_from_wkt_output_iterator
+\line {
+\until }
+*/
+template <typename Point, typename Out>
+inline void read_wkt(std::string const& wkt, Out out)
+{
+    ggl::concept::check<Point>();
+
+    // Todo: maybe take this from the string, or do not call initialize, such that
+    // any coordinate string is parsed and outputted
+    std::string const& tag = "linestring";
+
+    detail::wkt::tokenizer tokens(wkt, boost::char_separator<char>(" ", ",()"));
+    detail::wkt::tokenizer::iterator it;
+    if (detail::wkt::initialize<Point>(tokens, tag, wkt, it))
+    {
+        detail::wkt::container_inserter<Point>::apply(it, tokens.end(), wkt, out);
+    }
+}
+
+} // namespace ggl
+
+#endif // GGL_EXTENSIONS_GIS_IO_WKT_READ_WKT_HPP
Added: sandbox/ggl/formal_review/boost/ggl/extensions/gis/io/wkt/read_wkt_multi.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/extensions/gis/io/wkt/read_wkt_multi.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,105 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 2008-2009, Geodan, Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_EXTENSIONS_GIS_IO_WKT_READ_WKT_MULTI_HPP
+#define GGL_EXTENSIONS_GIS_IO_WKT_READ_WKT_MULTI_HPP
+
+#include <string>
+
+#include <ggl/multi/core/tags.hpp>
+#include <ggl/multi/core/point_type.hpp>
+
+#include <ggl/extensions/gis/io/wkt/read_wkt.hpp>
+#include <ggl/extensions/gis/io/wkt/detail/wkt_multi.hpp>
+
+
+namespace ggl
+{
+
+namespace detail { namespace wkt {
+
+template <typename MultiGeometry, template<typename> class Parser, typename PrefixPolicy>
+struct multi_parser
+{
+    static inline void apply(std::string const& wkt, MultiGeometry& geometry)
+    {
+        geometry.clear();
+
+        tokenizer tokens(wkt, boost::char_separator<char>(" ", ",()"));
+        tokenizer::iterator it;
+        if (initialize<MultiGeometry>(tokens, PrefixPolicy::apply(), wkt, it))
+        {
+            handle_open_parenthesis(it, tokens.end(), wkt);
+
+            // Parse sub-geometries
+            while(it != tokens.end() && *it != ")")
+            {
+                geometry.resize(geometry.size() + 1);
+                Parser
+                    <
+                        typename boost::range_value<MultiGeometry>::type
+                    >::apply(it, tokens.end(), wkt, geometry.back());
+                if (it != tokens.end() && *it == ",")
+                {
+                    // Skip "," after multi-element is parsed
+                    ++it;
+                }
+            }
+
+            handle_close_parenthesis(it, tokens.end(), wkt);
+        }
+    }
+};
+
+
+
+
+}} // namespace detail::wkt
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename MultiGeometry>
+struct read_wkt<multi_point_tag, MultiGeometry>
+    : detail::wkt::multi_parser
+            <
+                MultiGeometry,
+                detail::wkt::point_parser,
+                detail::wkt::prefix_multipoint
+            >
+{};
+
+
+template <typename MultiGeometry>
+struct read_wkt<multi_linestring_tag, MultiGeometry>
+    : detail::wkt::multi_parser
+            <
+                MultiGeometry,
+                detail::wkt::linestring_parser,
+                detail::wkt::prefix_multilinestring
+            >
+{};
+
+
+template <typename MultiGeometry>
+struct read_wkt<multi_polygon_tag, MultiGeometry>
+    : detail::wkt::multi_parser
+            <
+                MultiGeometry,
+                detail::wkt::polygon_parser,
+                detail::wkt::prefix_multipolygon
+            >
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+} // namespace ggl
+
+#endif // GGL_EXTENSIONS_GIS_IO_WKT_READ_WKT_MULTI_HPP
Added: sandbox/ggl/formal_review/boost/ggl/extensions/gis/io/wkt/stream_wkt.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/extensions/gis/io/wkt/stream_wkt.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,40 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 2008-2009, Geodan, Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_EXTENSIONS_GIS_IO_WKT_STREAM_WKT_HPP
+#define GGL_EXTENSIONS_GIS_IO_WKT_STREAM_WKT_HPP
+
+#include <ggl/extensions/gis/io/wkt/write_wkt.hpp>
+
+// This short file contains only one manipulator, streaming as WKT
+// Don't move contents to as_wkt, developers must be able to choose how to stream
+
+// Don't use namespace ggl, to enable the library to stream custom geometries which
+// are living outside the namespace ggl
+
+//namespace ggl
+//{
+
+
+/*!
+\brief Streams a geometry as Well-Known Text
+\ingroup wkt
+*/
+template<typename Char, typename Traits, typename Geometry>
+inline std::basic_ostream<Char,Traits>& operator<<
+    (
+        std::basic_ostream<Char,Traits> &os, 
+        Geometry const& geometry
+    )
+{
+    os << ggl::wkt(geometry);
+    return os;
+}
+
+//} // namespace ggl
+
+#endif // GGL_EXTENSIONS_GIS_IO_WKT_STREAM_WKT_HPP
Added: sandbox/ggl/formal_review/boost/ggl/extensions/gis/io/wkt/wkt.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/extensions/gis/io/wkt/wkt.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,19 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 2008-2009, Geodan, Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_EXTENSIONS_GIS_IO_WKT_WKT_HPP
+#define GGL_EXTENSIONS_GIS_IO_WKT_WKT_HPP
+
+
+#include <ggl/extensions/gis/io/wkt/read_wkt.hpp>
+#include <ggl/extensions/gis/io/wkt/write_wkt.hpp>
+
+#include <ggl/extensions/gis/io/wkt/read_wkt_multi.hpp>
+#include <ggl/extensions/gis/io/wkt/write_wkt_multi.hpp>
+
+
+#endif // GGL_EXTENSIONS_GIS_IO_WKT_WKT_HPP
Added: sandbox/ggl/formal_review/boost/ggl/extensions/gis/io/wkt/write_wkt.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/extensions/gis/io/wkt/write_wkt.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,360 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 2008-2009, Geodan, Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_EXTENSIONS_GIS_IO_WKT_WRITE_WKT_HPP
+#define GGL_EXTENSIONS_GIS_IO_WKT_WRITE_WKT_HPP
+
+#include <iostream>
+#include <string>
+
+#include <boost/concept/assert.hpp>
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/algorithms/convert.hpp>
+#include <ggl/core/exterior_ring.hpp>
+#include <ggl/core/interior_rings.hpp>
+#include <ggl/core/ring_type.hpp>
+
+#include <ggl/geometries/concepts/check.hpp>
+#include <ggl/geometries/linear_ring.hpp>
+
+#include <ggl/extensions/gis/io/wkt/detail/wkt.hpp>
+
+/*!
+\defgroup wkt wkt: parse and stream WKT (Well-Known Text)
+The wkt classes stream the specified geometry as \ref OGC Well Known Text (\ref WKT). It is defined for OGC geometries.
+It is therefore not defined for all geometries (e.g. not for circle)
+\note The implementation is independant from point type, point_xy and point_ll are supported,
+as well as points with more than two coordinates.
+*/
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace wkt {
+
+template <typename P, int I, int Count>
+struct stream_coordinate
+{
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>& os, P const& p)
+    {
+        os << (I > 0 ? " " : "") << get<I>(p);
+        stream_coordinate<P, I + 1, Count>::apply(os, p);
+    }
+};
+
+template <typename P, int Count>
+struct stream_coordinate<P, Count, Count>
+{
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>&, P const&)
+    {}
+};
+
+struct prefix_linestring_par
+{
+    static inline const char* apply() { return "LINESTRING("; }
+};
+
+struct prefix_ring_par_par
+{
+    // Note, double parentheses are intentional, indicating WKT ring begin/end
+    static inline const char* apply() { return "POLYGON(("; }
+};
+
+struct opening_parenthesis
+{
+    static inline const char* apply() { return "("; }
+};
+
+struct closing_parenthesis
+{
+    static inline const char* apply() { return ")"; }
+};
+
+struct double_closing_parenthesis
+{
+    static inline const char* apply() { return "))"; }
+};
+
+
+
+
+/*!
+\brief Stream points as \ref WKT
+*/
+template <typename Point, typename Policy>
+struct wkt_point
+{
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>& os, Point const& p)
+    {
+        os << Policy::apply() << "(";
+        stream_coordinate<Point, 0, dimension<Point>::type::value>::apply(os, p);
+        os << ")";
+    }
+};
+
+/*!
+\brief Stream ranges as WKT
+\note policy is used to stream prefix/postfix, enabling derived classes to override this
+*/
+template <typename Range, typename PrefixPolicy, typename SuffixPolicy>
+struct wkt_range
+{
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>& os,
+                Range const& range)
+    {
+        typedef typename boost::range_const_iterator<Range>::type iterator_type;
+
+        bool first = true;
+
+        os << PrefixPolicy::apply();
+
+        // TODO: check EMPTY here
+
+        for (iterator_type it = boost::begin(range);
+            it != boost::end(range);
+            ++it)
+        {
+            os << (first ? "" : ",");
+            stream_coordinate
+                <
+                    point_type, 0, dimension<point_type>::type::value
+                >::apply(os, *it);
+            first = false;
+        }
+
+        os << SuffixPolicy::apply();
+    }
+
+private:
+    typedef typename boost::range_value<Range>::type point_type;
+};
+
+/*!
+\brief Stream sequence of points as WKT-part, e.g. (1 2),(3 4)
+\note Used in polygon, all multi-geometries
+*/
+
+
+
+template <typename Range>
+struct wkt_sequence
+    : wkt_range
+        <
+            Range,
+            opening_parenthesis,
+            closing_parenthesis
+        >
+{};
+
+
+template <typename Polygon, typename PrefixPolicy>
+struct wkt_poly
+{
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>& os,
+                Polygon const& poly)
+    {
+        typedef typename ring_type<Polygon>::type ring;
+        typedef typename boost::range_const_iterator<
+                    typename interior_type<Polygon>::type>::type iterator;
+
+        os << PrefixPolicy::apply();
+        // TODO: check EMPTY here
+        os << "(";
+        wkt_sequence<ring>::apply(os, exterior_ring(poly));
+        for (iterator it = boost::begin(interior_rings(poly));
+            it != boost::end(interior_rings(poly));
+            ++it)
+        {
+            os << ",";
+            wkt_sequence<ring>::apply(os, *it);
+        }
+        os << ")";
+    }
+};
+
+
+template <typename Box>
+struct wkt_box
+{
+    typedef typename point_type<Box>::type point_type;
+
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>& os,
+                Box const& box)
+    {
+        // Convert to linear ring, then stream
+        typedef linear_ring<point_type> ring_type;
+        ring_type ring;
+        ggl::convert(box, ring);
+        os << "POLYGON(";
+        wkt_sequence<ring_type>::apply(os, ring);
+        os << ")";
+    }
+
+    private:
+
+        inline wkt_box()
+        {
+            // Only streaming of boxes with two dimensions is support, otherwise it is a polyhedron!
+            //assert_dimension<B, 2>();
+        }
+};
+
+}} // namespace detail::wkt
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch {
+
+template <typename Tag, typename Geometry>
+struct wkt {};
+
+
+template <typename Point>
+struct wkt<point_tag, Point>
+    : detail::wkt::wkt_point
+        <
+            Point,
+            detail::wkt::prefix_point
+        >
+{};
+
+
+template <typename Linestring>
+struct wkt<linestring_tag, Linestring>
+    : detail::wkt::wkt_range
+        <
+            Linestring,
+            detail::wkt::prefix_linestring_par,
+            detail::wkt::closing_parenthesis
+        >
+{};
+
+
+/*!
+\brief Specialization to stream a box as WKT
+\details A "box" does not exist in WKT.
+It is therefore streamed as a polygon
+*/
+template <typename Box>
+struct wkt<box_tag, Box>
+    : detail::wkt::wkt_box<Box>
+{};
+
+
+/*!
+\brief Specialization to stream a ring as WKT
+\details A "linear_ring" does not exist in WKT.
+A linear ring is equivalent to a polygon without inner rings
+It is therefore streamed as a polygon
+*/
+template <typename Ring>
+struct wkt<ring_tag, Ring>
+    : detail::wkt::wkt_range
+        <
+            Ring,
+            detail::wkt::prefix_ring_par_par,
+            detail::wkt::double_closing_parenthesis
+        >
+{};
+
+
+/*!
+\brief Specialization to stream polygon as WKT
+*/
+template <typename Polygon>
+struct wkt<polygon_tag, Polygon>
+    : detail::wkt::wkt_poly
+        <
+            Polygon,
+            detail::wkt::prefix_polygon
+        >
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+\brief Generic geometry template manipulator class, takes corresponding output class from traits class
+\ingroup wkt
+\details Stream manipulator, streams geometry classes as \ref WKT streams
+\par Example:
+Small example showing how to use the wkt class
+\dontinclude doxygen_1.cpp
+\skip example_as_wkt_point
+\line {
+\until }
+*/
+template <typename Geometry>
+class wkt_manipulator
+{
+public:
+
+    inline wkt_manipulator(Geometry const& g)
+        : m_geometry(g)
+    {}
+
+    template <typename Char, typename Traits>
+    inline friend std::basic_ostream<Char, Traits>& operator<<(
+            std::basic_ostream<Char, Traits>& os,
+            wkt_manipulator const& m)
+    {
+        dispatch::wkt
+            <
+                typename tag<Geometry>::type,
+                Geometry
+            >::apply(os, m.m_geometry);
+        os.flush();
+        return os;
+    }
+
+private:
+    Geometry const& m_geometry;
+};
+
+/*!
+\brief Main WKT-streaming function
+\ingroup wkt
+\par Example:
+Small example showing how to use the wkt helper function
+\dontinclude doxygen_1.cpp
+\skip example_as_wkt_vector
+\line {
+\until }
+*/
+template <typename Geometry>
+inline wkt_manipulator<Geometry> wkt(Geometry const& geometry)
+{
+    concept::check<const Geometry>();
+
+    return wkt_manipulator<Geometry>(geometry);
+}
+
+
+// Backward compatibility
+template <typename Geometry>
+inline wkt_manipulator<Geometry> make_wkt(Geometry const& geometry)
+{
+    concept::check<const Geometry>();
+
+    return wkt_manipulator<Geometry>(geometry);
+}
+
+} // namespace ggl
+
+#endif // GGL_EXTENSIONS_GIS_IO_WKT_WRITE_WKT_HPP
Added: sandbox/ggl/formal_review/boost/ggl/extensions/gis/io/wkt/write_wkt_multi.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/extensions/gis/io/wkt/write_wkt_multi.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,109 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 2008-2009, Geodan, Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_EXTENSIONS_GIS_IO_WKT_WRITE_WKT_MULTI_HPP
+#define GGL_EXTENSIONS_GIS_IO_WKT_WRITE_WKT_MULTI_HPP
+
+
+
+#include <ggl/multi/core/tags.hpp>
+
+#include <ggl/extensions/gis/io/wkt/write_wkt.hpp>
+#include <ggl/extensions/gis/io/wkt/detail/wkt_multi.hpp>
+
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace wkt {
+
+
+template <typename Multi, typename StreamPolicy, typename PrefixPolicy>
+struct wkt_multi
+{
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>& os,
+                Multi const& geometry)
+    {
+        os << PrefixPolicy::apply();
+        // TODO: check EMPTY here
+        os << "(";
+
+        for (typename boost::range_const_iterator<Multi>::type
+                    it = boost::begin(geometry);
+            it != boost::end(geometry);
+            ++it)
+        {
+            if (it != boost::begin(geometry))
+            {
+                os << ",";
+            }
+            StreamPolicy::apply(os, *it);
+        }
+
+        os << ")";
+    }
+};
+
+}} // namespace wkt::impl
+#endif
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch {
+
+
+template <typename Multi>
+struct wkt<multi_point_tag, Multi>
+    : detail::wkt::wkt_multi
+        <
+            Multi,
+            detail::wkt::wkt_point
+                <
+                    typename boost::range_value<Multi>::type,
+                    detail::wkt::prefix_null
+                >,
+            detail::wkt::prefix_multipoint
+        >
+{};
+
+
+template <typename Multi>
+struct wkt<multi_linestring_tag, Multi>
+    : detail::wkt::wkt_multi
+        <
+            Multi,
+            detail::wkt::wkt_sequence
+                <
+                    typename boost::range_value<Multi>::type
+                >,
+            detail::wkt::prefix_multilinestring
+        >
+{};
+
+
+template <typename Multi>
+struct wkt<multi_polygon_tag, Multi>
+    : detail::wkt::wkt_multi
+        <
+            Multi,
+            detail::wkt::wkt_poly
+                <
+                    typename boost::range_value<Multi>::type,
+                    detail::wkt::prefix_null
+                >,
+            detail::wkt::prefix_multipolygon
+        >
+{};
+
+} // namespace dispatch
+#endif
+
+}
+
+#endif // GGL_EXTENSIONS_GIS_IO_WKT_WRITE_WKT_MULTI_HPP
Added: sandbox/ggl/formal_review/boost/ggl/extensions/io/svg/write_svg.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/extensions/io/svg/write_svg.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,248 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_IO_SVG_WRITE_SVG_HPP
+#define GGL_IO_SVG_WRITE_SVG_HPP
+
+#include <iostream>
+#include <string>
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/core/exterior_ring.hpp>
+#include <ggl/core/interior_rings.hpp>
+#include <ggl/core/ring_type.hpp>
+
+#include <ggl/geometries/concepts/check.hpp>
+
+/*!
+\defgroup svg x Extension svg: Stream SVG (Scalable Vector Graphics)
+*/
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace svg {
+
+
+template <typename Point>
+struct svg_point
+{
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>& os,
+                Point const& p, std::string const& style, int size)
+    {
+        os << "<circle cx=\"" << p.x()
+            << "\" cy=\"" << p.y()
+            << "\" r=\"" << (size < 0 ? 5 : size)
+            << "\" style=\"" << style << "\"/>";
+    }
+};
+
+
+template <typename Box>
+struct svg_box
+{
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>& os,
+                Box const& box, std::string const& style, int size)
+    {
+        int x = ggl::get<ggl::min_corner, 0>(box);
+        int y = ggl::get<ggl::min_corner, 1>(box);
+        int width = std::abs(ggl::get<ggl::max_corner, 0>(box) - x);
+        int height = std::abs(ggl::get<ggl::max_corner, 1>(box) - y);
+
+        os << "<rect x=\"" << x << "\" y=\"" << y
+            << "\" width=\"" << width << "\" height=\"" << height
+            << "\" style=\"" << style << "\"/>";
+    }
+};
+
+
+/*!
+\brief Stream ranges as SVG
+\note policy is used to select type (polyline/polygon)
+*/
+template <typename Range, typename Policy>
+struct svg_range
+{
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>& os,
+        Range const& range, std::string const& style, int size)
+    {
+        typedef typename boost::range_const_iterator<Range>::type iterator;
+
+        bool first = true;
+
+        os << "<" << Policy::prefix() << " points=\"";
+
+        for (iterator it = boost::begin(range);
+            it != boost::end(range);
+            ++it, first = false)
+        {
+            os << (first ? "" : " " ) << it->x() << "," << it->y();
+        }
+        os << "\" style=\"" << style << Policy::style() << "\"/>";
+    }
+};
+
+
+
+template <typename Polygon>
+struct svg_poly
+{
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>& os,
+        Polygon const& polygon, std::string const& style, int size)
+    {
+        typedef typename ggl::ring_type<Polygon>::type ring_type;
+        typedef typename boost::range_const_iterator<ring_type>::type iterator_type;
+
+        bool first = true;
+        os << "<g fill-rule=\"evenodd\"><path d=\"";
+
+        ring_type const& ring = ggl::exterior_ring(polygon);
+        for (iterator_type it = boost::begin(ring);
+            it != boost::end(ring);
+            ++it, first = false)
+        {
+            os << (first ? "M" : " L") << " " << it->x() << "," << it->y();
+        }
+
+        // Inner rings:
+        {
+            typedef typename boost::range_const_iterator
+                <
+                    typename ggl::interior_type<Polygon>::type
+                >::type ring_iterator_type;
+            for (ring_iterator_type rit = boost::begin(interior_rings(polygon));
+                 rit != boost::end(interior_rings(polygon));
+                 ++rit)
+            {
+                first = true;
+                for (iterator_type it = boost::begin(*rit);
+                    it != boost::end(*rit);
+                    ++it, first = false)
+                {
+                    os << (first ? "M" : " L") << " " << it->x() << "," << it->y();
+                }
+            }
+        }
+        os << " z \" style=\"" << style << "\"/></g>";
+
+    }
+};
+
+
+
+struct prefix_linestring
+{
+    static inline const char* prefix() { return "polyline"; }
+    static inline const char* style() { return ";fill:none"; }
+};
+
+
+struct prefix_ring
+{
+    static inline const char* prefix() { return "polygon"; }
+    static inline const char* style() { return ""; }
+};
+
+
+
+}} // namespace detail::svg
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch {
+
+/*!
+\brief Dispatching base struct for SVG streaming, specialized below per geometry type
+\details Specializations should implement a static method "stream" to stream a geometry
+The static method should have the signature:
+
+template <typename Char, typename Traits>
+static inline void apply(std::basic_ostream<Char, Traits>& os, const G& geometry)
+*/
+template <typename GeometryTag, typename Geometry>
+struct svg {};
+
+template <typename Point>
+struct svg<point_tag, Point> : detail::svg::svg_point<Point> {};
+
+template <typename Box>
+struct svg<box_tag, Box> : detail::svg::svg_box<Box> {};
+
+template <typename Linestring>
+struct svg<linestring_tag, Linestring>
+    : detail::svg::svg_range<Linestring, detail::svg::prefix_linestring> {};
+
+template <typename Ring>
+struct svg<ring_tag, Ring>
+    : detail::svg::svg_range<Ring, detail::svg::prefix_ring> {};
+
+template <typename Polygon>
+struct svg<polygon_tag, Polygon>
+    : detail::svg::svg_poly<Polygon> {};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+\brief Generic geometry template manipulator class, takes corresponding output class from traits class
+\ingroup svg
+\details Stream manipulator, streams geometry classes as Virtual Earth shape
+*/
+template <typename G>
+class svg_manipulator
+{
+public:
+
+    inline svg_manipulator(G const& g, std::string const& style, int size)
+        : m_geometry(g)
+        , m_style(style)
+        , m_size(size)
+    {}
+
+    template <typename Char, typename Traits>
+    inline friend std::basic_ostream<Char, Traits>& operator<<(
+                    std::basic_ostream<Char, Traits>& os, svg_manipulator const& m)
+    {
+        dispatch::svg
+            <
+                typename tag<G>::type, G
+            >::apply(os, m.m_geometry, m.m_style, m.m_size);
+        os.flush();
+        return os;
+    }
+
+private:
+    G const& m_geometry;
+    std::string const& m_style;
+    int m_size;
+};
+
+/*!
+\brief Main svg function to stream geometries as SVG
+\ingroup svg
+*/
+template <typename Geometry>
+inline svg_manipulator<Geometry> svg(Geometry const& t, std::string const& style, int size = -1)
+{
+    concept::check<const Geometry>();
+
+    return svg_manipulator<Geometry>(t, style, size);
+}
+
+} // namespace ggl
+
+#endif // GGL_IO_SVG_WRITE_SVG_HPP
Added: sandbox/ggl/formal_review/boost/ggl/extensions/io/svg/write_svg_multi.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/extensions/io/svg/write_svg_multi.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,73 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_IO_SVG_WRITE_SVG_MULTI_HPP
+#define GGL_IO_SVG_WRITE_SVG_MULTI_HPP
+
+
+#include <ggl/extensions/io/svg/write_svg.hpp>
+
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace svg {
+
+
+template <typename MultiGeometry, typename Policy>
+struct svg_multi
+{
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>& os,
+        MultiGeometry const& multi, std::string const& style, int size)
+    {
+        for (typename boost::range_const_iterator<MultiGeometry>::type
+                    it = boost::begin(multi);
+            it != boost::end(multi);
+            ++it)
+        {
+            Policy::apply(os, *it, style, size);
+        }
+
+    }
+
+};
+
+
+
+}} // namespace detail::svg
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch {
+
+
+template <typename MultiPolygon>
+struct svg<multi_polygon_tag, MultiPolygon>
+    : detail::svg::svg_multi
+        <
+            MultiPolygon,
+            detail::svg::svg_poly
+                <
+                    typename boost::range_value<MultiPolygon>::type
+                >
+
+        >
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+
+} // namespace ggl
+
+#endif // GGL_IO_SVG_WRITE_SVG_MULTI_HPP
Added: sandbox/ggl/formal_review/boost/ggl/geometries/adapted/boost_array_as_linestring.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/geometries/adapted/boost_array_as_linestring.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,40 @@
+// Generic Geometry Library
+//
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_GEOMETRIES_ADAPTED_BOOST_ARRAY_AS_LINESTRING_HPP
+#define GGL_GEOMETRIES_ADAPTED_BOOST_ARRAY_AS_LINESTRING_HPP
+
+
+#ifdef GGL_ADAPTED_BOOST_ARRAY_RANGE_TAG_DEFINED
+#error Include only one headerfile to register tag for adapted boost::array
+#endif
+
+#define GGL_ADAPTED_BOOST_ARRAY_RANGE_TAG_DEFINED
+
+
+#include <boost/array.hpp>
+
+namespace ggl
+{
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+    template <typename T, size_t N>
+    struct tag< boost::array<T, N> >
+    {
+        typedef linestring_tag type;
+    };
+
+}
+#endif
+}
+
+
+#endif
Added: sandbox/ggl/formal_review/boost/ggl/geometries/adapted/boost_array_as_ring.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/geometries/adapted/boost_array_as_ring.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,40 @@
+// Generic Geometry Library
+//
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_GEOMETRIES_ADAPTED_BOOST_ARRAY_AS_RING_HPP
+#define GGL_GEOMETRIES_ADAPTED_BOOST_ARRAY_AS_RING_HPP
+
+
+#ifdef GGL_ADAPTED_BOOST_ARRAY_RANGE_TAG_DEFINED
+#error Include only one headerfile to register tag for adapted boost::array
+#endif
+
+#define GGL_ADAPTED_BOOST_ARRAY_RANGE_TAG_DEFINED
+
+
+#include <boost/array.hpp>
+
+namespace ggl
+{
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+    template <typename T, size_t N>
+    struct tag< boost::array<T, N> >
+    {
+        typedef ring_tag type;
+    };
+
+}
+#endif
+}
+
+
+#endif
Added: sandbox/ggl/formal_review/boost/ggl/geometries/adapted/c_array.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/geometries/adapted/c_array.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,88 @@
+// Generic Geometry Library
+//
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_GEOMETRIES_ADAPTED_C_ARRAY_HPP
+#define GGL_GEOMETRIES_ADAPTED_C_ARRAY_HPP
+
+#include <cstddef>
+
+#include <boost/type_traits/is_arithmetic.hpp>
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/cs.hpp>
+#include <ggl/core/coordinate_dimension.hpp>
+#include <ggl/core/coordinate_type.hpp>
+#include <ggl/core/tags.hpp>
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+// Create class and specialization to indicate the tag
+// for normal cases and the case that the type of the c-array is arithmetic
+template <bool>
+struct c_array_tag
+{
+    typedef geometry_not_recognized_tag type;
+};
+
+template <>
+struct c_array_tag<true>
+{
+    typedef point_tag type;
+};
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+// Assign the point-tag, preventing arrays of points getting a point-tag
+template <typename CoordinateType, std::size_t DimensionCount>
+struct tag<CoordinateType[DimensionCount]> 
+    : detail::c_array_tag<boost::is_arithmetic<CoordinateType>::value> {};
+
+template <typename CoordinateType, std::size_t DimensionCount>
+struct coordinate_type<CoordinateType[DimensionCount]>
+{
+    typedef CoordinateType type;
+};
+
+template <typename CoordinateType, std::size_t DimensionCount>
+struct dimension<CoordinateType[DimensionCount]>: boost::mpl::int_<DimensionCount> {};
+
+template <typename CoordinateType, std::size_t DimensionCount, std::size_t Dimension>
+struct access<CoordinateType[DimensionCount], Dimension>
+{
+    static inline CoordinateType get(const CoordinateType p[DimensionCount])
+    {
+        return p[Dimension];
+    }
+
+    static inline void set(CoordinateType p[DimensionCount], 
+        CoordinateType const& value)
+    {
+        p[Dimension] = value;
+    }
+};
+
+// The library user has
+// 1) either to specify the coordinate system
+// 2) or include <ggl/geometries/adapted/c_array__at_.hpp> where @=cartesian,geographic,...
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+} // namespace ggl
+
+#endif // GGL_GEOMETRIES_ADAPTED_C_ARRAY_HPP
Added: sandbox/ggl/formal_review/boost/ggl/geometries/adapted/c_array_cartesian.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/geometries/adapted/c_array_cartesian.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,37 @@
+// Generic Geometry Library
+//
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_GEOMETRIES_ADAPTED_C_ARRAY_CARTESIAN_HPP
+#define GGL_GEOMETRIES_ADAPTED_C_ARRAY_CARTESIAN_HPP
+
+#ifdef GGL_ADAPTED_C_ARRAY_COORDINATE_SYSTEM_DEFINED
+#error Include only one headerfile to register coordinate coordinate_system for adapted c array
+#endif
+
+#define GGL_ADAPTED_C_ARRAY_COORDINATE_SYSTEM_DEFINED
+
+
+#include <ggl/geometries/adapted/c_array.hpp>
+
+
+namespace ggl
+{
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+    template <typename T, int N>
+    struct coordinate_system<T[N]>
+    { typedef cs::cartesian type; };
+
+}
+#endif
+}
+
+
+#endif
Added: sandbox/ggl/formal_review/boost/ggl/geometries/adapted/std_as_linestring.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/geometries/adapted/std_as_linestring.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,66 @@
+// Generic Geometry Library
+//
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_GEOMETRIES_ADAPTED_STD_AS_LINESTRING_HPP
+#define GGL_GEOMETRIES_ADAPTED_STD_AS_LINESTRING_HPP
+
+
+#ifdef GGL_ADAPTED_STD_RANGE_TAG_DEFINED
+#error Include only one headerfile to register tag for adapted std:: containers or iterator pair
+#endif
+
+#define GGL_ADAPTED_STD_RANGE_TAG_DEFINED
+
+
+#include <vector>
+#include <deque>
+#include <list>
+#include <utility>
+
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/tag.hpp>
+#include <ggl/core/tags.hpp>
+
+
+namespace ggl
+{
+#ifndef DOXYGEN_NO_DETAIL
+namespace util
+{
+    struct std_as_linestring
+    {
+        typedef linestring_tag type;
+    };
+
+}
+#endif
+
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+    // specialization for an iterator pair (read only)
+    template <typename P> struct tag< std::pair<P, P> > : util::std_as_linestring {};
+
+    // Indicate that std::library is not used to add things to std::pair.
+    // Don't implement anything else -> adding points or clearing not possible
+    template <typename P> struct use_std< std::pair<P, P> > : boost::mpl::false_ {};
+
+    // specializations for a std:: containers: vector, deque, list
+    template <typename P> struct tag< std::vector<P> > : util::std_as_linestring {};
+    template <typename P> struct tag< std::deque<P> > : util::std_as_linestring {};
+    template <typename P> struct tag< std::list<P> > : util::std_as_linestring {};
+
+}
+#endif
+}
+
+
+#endif
Added: sandbox/ggl/formal_review/boost/ggl/geometries/adapted/std_as_ring.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/geometries/adapted/std_as_ring.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,43 @@
+// Generic Geometry Library
+//
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_GEOMETRIES_ADAPTED_STD_AS_RING_HPP
+#define GGL_GEOMETRIES_ADAPTED_STD_AS_RING_HPP
+
+
+#ifdef GGL_ADAPTED_STD_RANGE_TAG_DEFINED
+#error Include only one headerfile to register tag for adapted std:: containers or iterator pair
+#endif
+
+#define GGL_ADAPTED_STD_RANGE_TAG_DEFINED
+
+
+#include <vector>
+#include <deque>
+#include <list>
+#include <utility>
+
+namespace ggl
+{
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+    // specialization for an iterator pair
+    template <typename T> struct tag< std::pair<T, T> > { typedef ring_tag type; };
+
+    // specialization for a std:: containers: vector, deque, list
+    template <typename T> struct tag< std::vector<T> > { typedef ring_tag type; };
+    template <typename T> struct tag< std::deque<T> > { typedef ring_tag type; };
+    template <typename T> struct tag< std::list<T> > { typedef ring_tag type; };
+}
+#endif
+}
+
+
+#endif
Added: sandbox/ggl/formal_review/boost/ggl/geometries/adapted/std_pair_as_segment.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/geometries/adapted/std_pair_as_segment.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,90 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_GEOMETRIES_ADAPTED_STD_PAIR_AS_SEGMENT_HPP
+#define GGL_GEOMETRIES_ADAPTED_STD_PAIR_AS_SEGMENT_HPP
+
+// Only possible if the std::pair is not used for iterator/pair
+// (maybe it is possible to avoid that by detecting in the other file
+//  if an iterator was used in the pair)
+
+#ifdef GGL_ADAPTED_STD_RANGE_TAG_DEFINED
+#error Include only one headerfile to register tag for adapted std:: containers or iterator pair
+#endif
+
+#define GGL_ADAPTED_STD_RANGE_TAG_DEFINED
+
+
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/tag.hpp>
+#include <ggl/core/tags.hpp>
+
+
+namespace ggl
+{
+
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+
+template <typename Point>
+struct tag<std::pair<Point, Point> >
+{
+    typedef segment_tag type;
+};
+
+template <typename Point>
+struct point_type<std::pair<Point, Point> >
+{
+    typedef Point type;
+};
+
+template <typename Point, std::size_t Dimension>
+struct indexed_access<std::pair<Point, Point>, 0, Dimension>
+{
+    typedef typename ggl::coordinate_type<Point>::type coordinate_type;
+
+    static inline coordinate_type get(std::pair<Point, Point> const& s)
+    {
+        return ggl::get<Dimension>(s.first);
+    }
+
+    static inline void set(std::pair<Point, Point>& s, coordinate_type const& value)
+    {
+        ggl::set<Dimension>(s.first, value);
+    }
+};
+
+
+template <typename Point, std::size_t Dimension>
+struct indexed_access<std::pair<Point, Point>, 1, Dimension>
+{
+    typedef typename ggl::coordinate_type<Point>::type coordinate_type;
+
+    static inline coordinate_type get(std::pair<Point, Point> const& s)
+    {
+        return ggl::get<Dimension>(s.second);
+    }
+
+    static inline void set(std::pair<Point, Point>& s, coordinate_type const& value)
+    {
+        ggl::set<Dimension>(s.second, value);
+    }
+};
+
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+} // namespace ggl
+
+
+#endif // GGL_GEOMETRIES_ADAPTED_STD_PAIR_AS_SEGMENT_HPP
Added: sandbox/ggl/formal_review/boost/ggl/geometries/adapted/tuple.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/geometries/adapted/tuple.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,120 @@
+// Generic Geometry Library
+//
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_GEOMETRIES_ADAPTED_TUPLE_HPP
+#define GGL_GEOMETRIES_ADAPTED_TUPLE_HPP
+
+#include <boost/tuple/tuple.hpp>
+
+#include <ggl/core/coordinate_dimension.hpp>
+#include <ggl/core/coordinate_type.hpp>
+#include <ggl/core/point_type.hpp>
+#include <ggl/core/tags.hpp>
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+// boost::tuple, 2D
+template <typename CoordinateType>
+struct coordinate_type<boost::tuple<CoordinateType, CoordinateType> >
+{
+    typedef CoordinateType type;
+};
+
+template <typename CoordinateType>
+struct dimension<boost::tuple<CoordinateType, CoordinateType> > 
+    : boost::mpl::int_<2> 
+{};
+
+template <typename CoordinateType, std::size_t Dimension>
+struct access
+    <
+        boost::tuple<CoordinateType, CoordinateType>,
+        Dimension
+    >
+{
+    static inline CoordinateType get(
+        boost::tuple<CoordinateType, CoordinateType> const& point)
+    {
+        return point.template get<Dimension>();
+    }
+
+    static inline void set(boost::tuple<CoordinateType, CoordinateType>& point, 
+        CoordinateType const& value)
+    {
+        point.template get<Dimension>() = value;
+    }
+};
+
+template <typename CoordinateType>
+struct tag<boost::tuple<CoordinateType, CoordinateType> >
+{
+    typedef point_tag type;
+};
+
+// boost::tuple, 3D
+template <typename CoordinateType>
+struct coordinate_type
+    <
+        boost::tuple<CoordinateType, CoordinateType, CoordinateType> 
+    >
+{
+    typedef CoordinateType type;
+};
+
+template <typename CoordinateType>
+struct dimension<boost::tuple<CoordinateType, CoordinateType, CoordinateType> > 
+    : boost::mpl::int_<3> 
+{};
+
+template <typename CoordinateType, std::size_t Dimension>
+struct access
+    <
+        boost::tuple<CoordinateType, CoordinateType, CoordinateType>,
+        Dimension 
+    >
+{
+    static inline CoordinateType get(
+        boost::tuple
+            <
+                CoordinateType, CoordinateType, CoordinateType
+            > const& point)
+    {
+        return point.template get<Dimension>();
+    }
+
+    static inline void set(
+        boost::tuple<CoordinateType, CoordinateType, CoordinateType>& point, 
+        CoordinateType const& value)
+    {
+        point.template get<Dimension>() = value;
+    }
+};
+
+template <typename CoordinateType>
+struct tag<boost::tuple<CoordinateType, CoordinateType, CoordinateType> >
+{
+    typedef point_tag type;
+};
+
+// The library user has
+// 1) either to specify the coordinate system using a traits class
+// 2) or include <ggl/geometries/adapted/tuple__at_.hpp> 
+//          where @=cartesian,geographic,...
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+} // namespace ggl
+
+#endif // GGL_GEOMETRIES_ADAPTED_TUPLE_HPP
+
Added: sandbox/ggl/formal_review/boost/ggl/geometries/adapted/tuple_cartesian.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/geometries/adapted/tuple_cartesian.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,41 @@
+// Generic Geometry Library
+//
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_GEOMETRIES_ADAPTED_TUPLE_CARTESIAN_HPP
+#define GGL_GEOMETRIES_ADAPTED_TUPLE_CARTESIAN_HPP
+
+#ifdef GGL_ADAPTED_TUPLE_COORDINATE_SYSTEM_DEFINED
+#error Include only one headerfile to register coordinate coordinate_system for adapted tuple
+#endif
+
+#define GGL_ADAPTED_TUPLE_COORDINATE_SYSTEM_DEFINED
+
+
+#include <ggl/geometries/adapted/tuple.hpp>
+
+
+namespace ggl
+{
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+    template <typename T>
+    struct coordinate_system<boost::tuple<T, T> >
+    { typedef cs::cartesian type; };
+
+    template <typename T>
+    struct coordinate_system<boost::tuple<T, T, T> >
+    { typedef cs::cartesian type; };
+
+}
+#endif
+}
+
+
+#endif
Added: sandbox/ggl/formal_review/boost/ggl/geometries/box.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/geometries/box.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,121 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_GEOMETRIES_BOX_HPP
+#define GGL_GEOMETRIES_BOX_HPP
+
+#include <cstddef>
+
+#include <boost/concept/assert.hpp>
+
+#include <ggl/geometries/concepts/point_concept.hpp>
+
+#include <ggl/util/copy.hpp>
+
+namespace ggl
+{
+
+/*!
+    \brief Class box: defines a box made of two describing points
+    \ingroup geometries
+    \details Box is always described by a min_corner() and a max_corner() point. If another
+        rectangle is used, use linear_ring or polygon.
+    \note Boxes are for selections and for calculating the envelope of geometries. Not all algorithms
+    are implemented for box. Boxes are also used in Spatial Indexes.
+    \tparam Point point type. The box takes a point type as template parameter.
+    The point type can be any point type.
+    It can be 2D but can also be 3D or more dimensional.
+    The box can also take a latlong point type as template parameter.
+ */
+
+template<typename Point>
+class box
+{
+    BOOST_CONCEPT_ASSERT( (concept::Point<Point>) );
+
+public:
+
+    inline box() {}
+
+    /*!
+        \brief Constructor taking the minimum corner point and the maximum corner point
+    */
+    inline box(Point const& min_corner, Point const& max_corner)
+    {
+        copy_coordinates(min_corner, m_min_corner);
+        copy_coordinates(max_corner, m_max_corner);
+    }
+
+    inline Point const& min_corner() const { return m_min_corner; }
+    inline Point const& max_corner() const { return m_max_corner; }
+
+    inline Point& min_corner() { return m_min_corner; }
+    inline Point& max_corner() { return m_max_corner; }
+
+private:
+
+    Point m_min_corner;
+    Point m_max_corner;
+};
+
+
+// Traits specializations for box above
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+template <typename Point>
+struct tag<box<Point> >
+{
+    typedef box_tag type;
+};
+
+template <typename Point>
+struct point_type<box<Point> >
+{
+    typedef Point type;
+};
+
+template <typename Point, std::size_t Dimension>
+struct indexed_access<box<Point>, min_corner, Dimension>
+{
+    typedef typename ggl::coordinate_type<Point>::type coordinate_type;
+
+    static inline coordinate_type get(box<Point> const& b)
+    {
+        return ggl::get<Dimension>(b.min_corner());
+    }
+
+    static inline void set(box<Point>& b, coordinate_type const& value)
+    {
+        ggl::set<Dimension>(b.min_corner(), value);
+    }
+};
+
+template <typename Point, std::size_t Dimension>
+struct indexed_access<box<Point>, max_corner, Dimension>
+{
+    typedef typename ggl::coordinate_type<Point>::type coordinate_type;
+
+    static inline coordinate_type get(box<Point> const& b)
+    {
+        return ggl::get<Dimension>(b.max_corner());
+    }
+
+    static inline void set(box<Point>& b, coordinate_type const& value)
+    {
+        ggl::set<Dimension>(b.max_corner(), value);
+    }
+};
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+} // namespace ggl
+
+#endif // GGL_GEOMETRIES_BOX_HPP
Added: sandbox/ggl/formal_review/boost/ggl/geometries/cartesian2d.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/geometries/cartesian2d.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,28 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_GEOMETRIES_CARTESIAN2D_HPP
+#define GGL_GEOMETRIES_CARTESIAN2D_HPP
+
+// Predeclare common Cartesian 2D points for convenience
+
+#include <ggl/geometries/geometries.hpp>
+
+namespace ggl
+{
+
+typedef point_xy<double, cs::cartesian> point_2d;
+typedef linestring<point_2d> linestring_2d;
+typedef linear_ring<point_2d> ring_2d;
+typedef polygon<point_2d> polygon_2d;
+typedef box<point_2d> box_2d;
+typedef segment<point_2d> segment_2d;
+
+} // namespace ggl
+
+#endif // GGL_GEOMETRIES_CARTESIAN2D_HPP
Added: sandbox/ggl/formal_review/boost/ggl/geometries/cartesian3d.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/geometries/cartesian3d.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,27 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_CARTESIAN3D_HPP
+#define GGL_CARTESIAN3D_HPP
+
+// Predeclare common Cartesian 3D points for convenience
+
+#include <ggl/geometries/geometries.hpp>
+
+namespace ggl
+{
+typedef point<double, 3, cs::cartesian> point_3d;
+typedef linestring<point_3d> linestring_3d;
+typedef linear_ring<point_3d> ring_3d;
+typedef polygon<point_3d> polygon_3d;
+typedef box<point_3d> box_3d;
+
+}
+
+
+#endif // GGL_CARTESIAN3D_HPP
Added: sandbox/ggl/formal_review/boost/ggl/geometries/concepts/box_concept.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/geometries/concepts/box_concept.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,131 @@
+// Generic Geometry Library
+//
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_GEOMETRIES_CONCEPTS_BOX_CONCEPT_HPP
+#define GGL_GEOMETRIES_CONCEPTS_BOX_CONCEPT_HPP
+
+
+#include <cstddef>
+
+#include <boost/concept_check.hpp>
+
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/coordinate_dimension.hpp>
+#include <ggl/core/point_type.hpp>
+
+
+
+namespace ggl { namespace concept {
+
+
+/*!
+\brief Box concept
+\ingroup concepts
+\par Formal definition:
+The box concept is defined as following:
+- there must be a specialization of traits::tag defining box_tag as type
+- there must be a specialization of traits::point_type to define the
+  underlying point type (even if it does not consist of points, it should define
+  this type, to indicate the points it can work with)
+- there must be a specialization of traits::indexed_access, per index
+  (min_corner, max_corner) and per dimension, with two functions:
+  - get to get a coordinate value
+  - set to set a coordinate value (this one is not checked for ConstBox)
+*/
+template <typename Geometry>
+class Box
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+    typedef typename point_type<Geometry>::type point_type;
+
+
+    template
+    <
+        std::size_t Index,
+        std::size_t Dimension,
+        std::size_t DimensionCount
+    >
+    struct dimension_checker
+    {
+        static void apply()
+        {
+            Geometry* b;
+            ggl::set<Index, Dimension>(*b, ggl::get<Index, Dimension>(*b));
+            dimension_checker<Index, Dimension + 1, DimensionCount>::apply();
+        }
+    };
+
+    template <std::size_t Index, std::size_t DimensionCount>
+    struct dimension_checker<Index, DimensionCount, DimensionCount>
+    {
+        static void apply() {}
+    };
+
+public :
+    BOOST_CONCEPT_USAGE(Box)
+    {
+        static const std::size_t n = dimension<Geometry>::type::value;
+        dimension_checker<min_corner, 0, n>::apply();
+        dimension_checker<max_corner, 0, n>::apply();
+    }
+#endif
+};
+
+
+/*!
+\brief Box concept (const version)
+\ingroup const_concepts
+\details The ConstBox concept apply the same as the Box concept,
+but does not apply write access.
+*/
+template <typename Geometry>
+class ConstBox
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+    typedef typename point_type<Geometry>::type point_type;
+    typedef typename coordinate_type<Geometry>::type coordinate_type;
+
+    template
+    <
+        std::size_t Index,
+        std::size_t Dimension,
+        std::size_t DimensionCount
+    >
+    struct dimension_checker
+    {
+        static void apply()
+        {
+            const Geometry* b = 0;
+            coordinate_type coord(ggl::get<Index, Dimension>(*b));
+            boost::ignore_unused_variable_warning(coord);
+            dimension_checker<Index, Dimension + 1, DimensionCount>::apply();
+        }
+    };
+
+    template <std::size_t Index, std::size_t DimensionCount>
+    struct dimension_checker<Index, DimensionCount, DimensionCount>
+    {
+        static void apply() {}
+    };
+
+public :
+    BOOST_CONCEPT_USAGE(ConstBox)
+    {
+        static const std::size_t n = dimension<Geometry>::type::value;
+        dimension_checker<min_corner, 0, n>::apply();
+        dimension_checker<max_corner, 0, n>::apply();
+    }
+#endif
+};
+
+}} // namespace ggl::concept
+
+
+#endif // GGL_GEOMETRIES_CONCEPTS_BOX_CONCEPT_HPP
Added: sandbox/ggl/formal_review/boost/ggl/geometries/concepts/check.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/geometries/concepts/check.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,208 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 2009, Geodan, Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_GEOMETRIES_CONCEPTS_CHECK_HPP
+#define GGL_GEOMETRIES_CONCEPTS_CHECK_HPP
+
+/*!
+\defgroup concepts geometry concepts: defines and checks concepts for geometries
+
+All GGL algorithms use concepts for their geometries. This means that all
+algorithms work on the GGL-provided geometries (point, linestring, etc) but
+also on custom geometries.
+
+By declaring registration macro's or by specializating traits classes it is
+possible to adapt custom or legacy geometries to fulfil  the GGL geometry
+concepts.
+
+GGL algorithms check the concepts of the input geometries.
+Concept checking is done using BCCL (Boost Concept Check Library).
+
+This means that geometries provided by library users, or legacy geometries, or
+plain arrays, or boost tuples, all can be handled by the Generic Geometry
+Library. Also std::vector of points, or tuples can be handled either as a
+linestring or as a linear ring (polygon without holes).
+
+There are concepts for
+- points
+- segment
+- box
+- linestring
+- (linear) ring
+- polygon
+- multi point
+- multi linestring
+- multi polygon
+
+The Generic Geometry Library uses the Boost Range Library to iterate through
+standard containers, boost arrays, c-arrays.
+So:
+- linestring
+- (linear) ring
+
+are all just ranges. So a std::vector, std::deque, boost::array,
+iterator pair or c-array will be accepted as such.
+
+Also the multi geometries:
+- multi point
+- multi linestring
+- multi polygon
+are considered as ranges of respectively points, linestrings and polygons.
+
+*/
+
+
+#include <boost/concept_check.hpp>
+#include <boost/concept/requires.hpp>
+
+#include <boost/type_traits/is_const.hpp>
+
+#include <ggl/core/tag.hpp>
+
+#include <ggl/geometries/concepts/box_concept.hpp>
+#include <ggl/geometries/concepts/linestring_concept.hpp>
+#include <ggl/geometries/concepts/point_concept.hpp>
+#include <ggl/geometries/concepts/polygon_concept.hpp>
+#include <ggl/geometries/concepts/ring_concept.hpp>
+
+
+namespace ggl {
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace concept_check {
+
+template <typename Concept>
+class check
+{
+    BOOST_CONCEPT_ASSERT((Concept ));
+};
+
+}} // namespace detail::check
+#endif // DOXYGEN_NO_DETAIL
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename GeometryTag, typename Geometry, bool IsConst>
+struct check
+{};
+
+
+template <typename Geometry>
+struct check<point_tag, Geometry, true>
+    : detail::concept_check::check<concept::ConstPoint<Geometry> >
+{};
+
+
+template <typename Geometry>
+struct check<point_tag, Geometry, false>
+    : detail::concept_check::check<concept::Point<Geometry> >
+{};
+
+
+template <typename Geometry>
+struct check<linestring_tag, Geometry, true>
+    : detail::concept_check::check<concept::ConstLinestring<Geometry> >
+{};
+
+
+template <typename Geometry>
+struct check<linestring_tag, Geometry, false>
+    : detail::concept_check::check<concept::Linestring<Geometry> >
+{};
+
+
+template <typename Geometry>
+struct check<polygon_tag, Geometry, true>
+    : detail::concept_check::check<concept::ConstPolygon<Geometry> >
+{};
+
+
+template <typename Geometry>
+struct check<polygon_tag, Geometry, false>
+    : detail::concept_check::check<concept::Polygon<Geometry> >
+{};
+
+
+template <typename Geometry>
+struct check<box_tag, Geometry, true>
+    : detail::concept_check::check<concept::ConstBox<Geometry> >
+{};
+
+
+template <typename Geometry>
+struct check<box_tag, Geometry, false>
+    : detail::concept_check::check<concept::Box<Geometry> >
+{};
+
+
+
+} // namespace dispatch
+#endif
+
+
+
+
+namespace concept {
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail {
+
+
+template <typename Geometry, bool IsConst>
+struct checker : dispatch::check
+    <
+        typename tag<Geometry>::type,
+        Geometry,
+        IsConst
+    >
+{};
+
+
+}
+#endif // DOXYGEN_NO_DETAIL
+
+
+/*!
+    \brief Checks, in compile-time, the concept of any geometry
+    \ingroup concepts
+*/
+template <typename Geometry>
+inline void check()
+{
+    detail::checker<Geometry, boost::is_const<Geometry>::type::value> c;
+    boost::ignore_unused_variable_warning(c);
+}
+
+
+/*!
+    \brief Checks, in compile-time, the concept of two geometries, and if they
+        have equal dimensions
+    \ingroup concepts
+*/
+template <typename Geometry1, typename Geometry2>
+inline void check_concepts_and_equal_dimensions()
+{
+    check<Geometry1>();
+    check<Geometry2>();
+    assert_dimension_equal<Geometry1, Geometry2>();
+}
+
+
+} // namespace concept
+
+
+} // namespace ggl
+
+
+#endif // GGL_GEOMETRIES_CONCEPTS_CHECK_HPP
Added: sandbox/ggl/formal_review/boost/ggl/geometries/concepts/detail/check_append.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/geometries/concepts/detail/check_append.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,58 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_GEOMETRIES_CONCEPTS_DETAIL_CHECK_APPEND_HPP
+#define GGL_GEOMETRIES_CONCEPTS_DETAIL_CHECK_APPEND_HPP
+
+
+#include <boost/type_traits/remove_const.hpp>
+
+#include <ggl/core/access.hpp>
+
+
+namespace ggl { namespace concept {
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+    template <typename Geometry, typename Point, bool UseStd>
+    struct check_append
+    {};
+
+    template <typename Geometry, typename Point>
+    struct check_append<Geometry, Point, true>
+    {
+        static void apply(Geometry& geometry, Point const& p)
+        {
+            geometry.push_back(p);
+        }
+    };
+
+
+    template <typename Geometry, typename Point>
+    struct check_append<Geometry, Point, false>
+    {
+        static void apply(Geometry& geometry, Point const& p)
+        {
+            ggl::traits::append_point
+                <
+                     typename boost::remove_const<Geometry>::type,
+                     Point
+                >::apply(geometry, p, -1, -1);
+        }
+    };
+}
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace ggl::concept
+
+
+#endif // GGL_GEOMETRIES_CONCEPTS_DETAIL_CHECK_APPEND_HPP
Added: sandbox/ggl/formal_review/boost/ggl/geometries/concepts/detail/check_clear.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/geometries/concepts/detail/check_clear.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,59 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_GEOMETRIES_CONCEPTS_DETAIL_CHECK_CLEAR_HPP
+#define GGL_GEOMETRIES_CONCEPTS_DETAIL_CHECK_CLEAR_HPP
+
+
+#include <boost/type_traits/remove_const.hpp>
+
+#include <ggl/core/access.hpp>
+
+
+namespace ggl { namespace concept {
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+    template <typename Geometry, bool UseStd>
+    struct check_clear
+    {};
+
+    template <typename Geometry>
+    struct check_clear<Geometry, true>
+    {
+        static void apply(Geometry& geometry)
+        {
+            geometry.clear();
+        }
+    };
+
+
+    template <typename Geometry>
+    struct check_clear<Geometry, false>
+    {
+        static void apply(Geometry& geometry)
+        {
+            ggl::traits::clear
+                <
+                     typename boost::remove_const<Geometry>::type
+                >::apply(geometry);
+        }
+    };
+
+}
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace ggl::concept
+
+
+#endif // GGL_GEOMETRIES_CONCEPTS_DETAIL_CHECK_CLEAR_HPP
Added: sandbox/ggl/formal_review/boost/ggl/geometries/concepts/linestring_concept.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/geometries/concepts/linestring_concept.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,130 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_GEOMETRIES_CONCEPTS_LINESTRING_CONCEPT_HPP
+#define GGL_GEOMETRIES_CONCEPTS_LINESTRING_CONCEPT_HPP
+
+
+#include <boost/concept_check.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/point_type.hpp>
+
+#include <ggl/geometries/concepts/point_concept.hpp>
+
+#include <ggl/geometries/concepts/detail/check_clear.hpp>
+#include <ggl/geometries/concepts/detail/check_append.hpp>
+
+
+namespace ggl { namespace concept {
+
+
+/*!
+\brief Linestring concept
+\ingroup concepts
+\par Formal definition:
+The linestring concept is defined as following:
+- there must be a specialization of traits::tag defining linestring_tag as type
+- it must behave like a Boost.Range
+- either it can behave like the std library, having push_back and clear
+- or it can implement a mechanism for clearing and adding points:
+   - there can be a specialization of traits::use_std class indicating
+     that it does not use the standard library (for modifications)
+   - there should then be a specialization of traits::clear
+     to make a linestring empty
+   - there should then be a specialization of traits::append_point
+     to add a point to a linestring
+
+\note to fulfil the concepts, no traits class has to be specialized to
+define the point type. The point type is taken using boost::range_value<X>::type
+
+\par Example:
+
+A custom linestring, defining the necessary specializations to fulfil to the concept.
+
+Suppose that the following linestring is defined:
+\dontinclude doxygen_5.cpp
+\skip custom_linestring1
+\until };
+
+It can then be adapted to the concept as following:
+\dontinclude doxygen_5.cpp
+\skip adapt custom_linestring1
+\until }}
+
+\note
+- There is also the registration macro GEOMETRY_REGISTER_LINESTRING
+- For registration of std::vector<P> (and deque, and list) it is enough to
+include the header-file geometries/adapted/std_as_linestring.hpp. That registers
+a vector as a linestring (so it cannot be registered as a linear ring then,
+in the same source code).
+
+
+*/
+
+template <typename Geometry>
+class Linestring
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+    typedef typename point_type<Geometry>::type point_type;
+
+    BOOST_CONCEPT_ASSERT( (concept::Point<point_type>) );
+    BOOST_CONCEPT_ASSERT( (boost::RandomAccessRangeConcept<Geometry>) );
+
+
+public :
+
+    BOOST_CONCEPT_USAGE(Linestring)
+    {
+        // Check if it can be modified
+        static const bool use_std = traits::use_std
+            <
+                typename boost::remove_const<Geometry>::type
+            >::value;
+
+        Geometry* ls;
+        detail::check_clear<Geometry, use_std>::apply(*ls);
+
+        point_type* p;
+        detail::check_append<Geometry, point_type, use_std>::apply(*ls, *p);
+    }
+#endif
+};
+
+
+/*!
+\brief Linestring concept (const version)
+\ingroup const_concepts
+\details The ConstLinestring concept check the same as the Linestring concept,
+but does not check write access.
+*/
+template <typename Geometry>
+class ConstLinestring
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+    typedef typename point_type<Geometry>::type point_type;
+
+    BOOST_CONCEPT_ASSERT( (concept::ConstPoint<point_type>) );
+    BOOST_CONCEPT_ASSERT( (boost::RandomAccessRangeConcept<Geometry>) );
+
+
+public :
+
+    BOOST_CONCEPT_USAGE(ConstLinestring)
+    {
+    }
+#endif
+};
+
+}} // namespace ggl::concept
+
+
+#endif // GGL_GEOMETRIES_CONCEPTS_LINESTRING_CONCEPT_HPP
Added: sandbox/ggl/formal_review/boost/ggl/geometries/concepts/point_concept.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/geometries/concepts/point_concept.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,167 @@
+// Generic Geometry Library Point concept
+//
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_GEOMETRIES_CONCEPTS_POINT_CONCEPT_HPP
+#define GGL_GEOMETRIES_CONCEPTS_POINT_CONCEPT_HPP
+
+#include <cstddef>
+
+#include <boost/concept_check.hpp>
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/coordinate_dimension.hpp>
+#include <ggl/core/coordinate_system.hpp>
+
+
+
+
+namespace ggl { namespace concept {
+
+/*!
+\brief Point concept
+\ingroup concepts
+
+\par Formal definition:
+The point concept is defined as following:
+- there must be a specialization of traits::tag defining point_tag as type
+- there must be a specialization of traits::coordinate_type defining the type
+  of its coordinates
+- there must be a specialization of traits::coordinate_system defining its
+  coordinate system (cartesian, spherical, etc)
+- there must be a specialization of traits::dimension defining its number
+  of dimensions (2, 3, ...) (derive it conveniently
+  from boost::mpl::int_<X> for X-D)
+- there must be a specialization of traits::access, per dimension,
+  with two functions:
+  - \b get to get a coordinate value
+  - \b set to set a coordinate value (this one is not checked for ConstPoint)
+
+\par Example:
+
+A legacy point, defining the necessary specializations to fulfil to the concept.
+
+Suppose that the following point is defined:
+\dontinclude doxygen_5.cpp
+\skip legacy_point1
+\until };
+
+It can then be adapted to the concept as following:
+\dontinclude doxygen_5.cpp
+\skip adapt legacy_point1
+\until }}
+
+Note that it is done like above to show the system. Users will normally use the registration macro.
+
+\par Example:
+
+A read-only legacy point, using a macro to fulfil to the ConstPoint concept.
+It cannot be modified by the library but can be used in all algorithms where
+points are not modified.
+
+The point looks like the following:
+
+\dontinclude doxygen_5.cpp
+\skip legacy_point2
+\until };
+
+It uses the macro as following:
+\dontinclude doxygen_5.cpp
+\skip adapt legacy_point2
+\until end adaptation
+
+*/
+
+template <typename Geometry>
+class Point
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+
+    typedef typename coordinate_type<Geometry>::type ctype;
+    typedef typename coordinate_system<Geometry>::type csystem;
+
+    enum { ccount = dimension<Geometry>::value };
+
+
+    template <typename P, std::size_t Dimension, std::size_t DimensionCount>
+    struct dimension_checker
+    {
+        static void apply()
+        {
+            P* p;
+            ggl::set<Dimension>(*p, ggl::get<Dimension>(*p));
+            dimension_checker<P, Dimension+1, DimensionCount>::apply();
+        }
+    };
+
+
+    template <typename P, std::size_t DimensionCount>
+    struct dimension_checker<P, DimensionCount, DimensionCount>
+    {
+        static void apply() {}
+    };
+
+public:
+
+    /// BCCL macro to apply the Point concept
+    BOOST_CONCEPT_USAGE(Point)
+    {
+        dimension_checker<Geometry, 0, ccount>::apply();
+    }
+#endif
+};
+
+
+/*!
+\brief point concept (const version)
+\ingroup const_concepts
+\details The ConstPoint concept apply the same as the Point concept,
+but does not apply write access.
+*/
+template <typename Geometry>
+class ConstPoint
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+
+    typedef typename coordinate_type<Geometry>::type ctype;
+    typedef typename coordinate_system<Geometry>::type csystem;
+
+    enum { ccount = dimension<Geometry>::value };
+
+
+    template <typename P, std::size_t Dimension, std::size_t DimensionCount>
+    struct dimension_checker
+    {
+        static void apply()
+        {
+            const P* p = 0;
+            ctype coord(ggl::get<Dimension>(*p));
+            boost::ignore_unused_variable_warning(coord);
+            dimension_checker<P, Dimension+1, DimensionCount>::apply();
+        }
+    };
+
+
+    template <typename P, std::size_t DimensionCount>
+    struct dimension_checker<P, DimensionCount, DimensionCount>
+    {
+        static void apply() {}
+    };
+
+public:
+
+    /// BCCL macro to apply the ConstPoint concept
+    BOOST_CONCEPT_USAGE(ConstPoint)
+    {
+        dimension_checker<Geometry, 0, ccount>::apply();
+    }
+#endif
+};
+
+}} // namespace ggl::concept
+
+#endif // GGL_GEOMETRIES_CONCEPTS_POINT_CONCEPT_HPP
Added: sandbox/ggl/formal_review/boost/ggl/geometries/concepts/polygon_concept.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/geometries/concepts/polygon_concept.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,145 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_GEOMETRIES_CONCEPTS_POLYGON_CONCEPT_HPP
+#define GGL_GEOMETRIES_CONCEPTS_POLYGON_CONCEPT_HPP
+
+#include <boost/concept_check.hpp>
+#include <boost/range/concepts.hpp>
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/exterior_ring.hpp>
+#include <ggl/core/interior_rings.hpp>
+#include <ggl/core/point_type.hpp>
+#include <ggl/core/ring_type.hpp>
+
+#include <ggl/geometries/concepts/point_concept.hpp>
+#include <ggl/geometries/concepts/ring_concept.hpp>
+
+namespace ggl { namespace concept {
+
+
+/*!
+\brief Polygon concept
+\ingroup concepts
+\par Formal definition:
+The polygon concept is defined as following:
+- there must be a specialization of traits::tag defining polygon_tag as type
+- there must be a specialization of traits::ring_type defining the type of its
+exterior ring and interior rings as type
+- there must be a specialization of traits::interior_type defining the type of
+the collection of its interior rings as type
+- there must be a specialization of traits::exterior_ring
+  with two functions named "get",
+  returning the exterior ring, a const version and a mutable version
+- there must be a specialization of traits::interior_rings
+  with two functions named "get", returning the interior rings,
+  a const version and a mutable version
+
+\note to fulfil the concepts, no traits class has to be specialized to
+define the point type. The point type is automatically defined as
+typename range_value<typename ring_type<P>::type>::type
+*/
+template <typename Geometry>
+class Polygon
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+    typedef typename point_type<Geometry>::type point_type;
+    typedef typename ring_type<Geometry>::type ring_type;
+    typedef typename interior_type<Geometry>::type interior_type;
+
+    BOOST_CONCEPT_ASSERT( (concept::Point<point_type>) );
+    BOOST_CONCEPT_ASSERT( (concept::Ring<ring_type>) );
+
+    BOOST_CONCEPT_ASSERT( (boost::RandomAccessRangeConcept<interior_type>) );
+
+    struct checker
+    {
+        static inline void apply()
+        {
+            Geometry* poly;
+            ring_type& e = exterior_ring(*poly);
+            ring_type const& ce = exterior_ring(*poly);
+
+            interior_type& i = interior_rings(*poly);
+            interior_type const& ci = interior_rings(*poly);
+
+            boost::ignore_unused_variable_warning(e);
+            boost::ignore_unused_variable_warning(ce);
+            boost::ignore_unused_variable_warning(i);
+            boost::ignore_unused_variable_warning(ci);
+            boost::ignore_unused_variable_warning(poly);
+        }
+
+    };
+
+public:
+
+
+    BOOST_CONCEPT_USAGE(Polygon)
+    {
+        // Check if it can be modified
+        // TODO
+
+        //Geometry* poly;
+        //clear(*poly);
+        //append(*poly, point_type());
+
+        checker::apply();
+    }
+#endif
+};
+
+
+/*!
+\brief Polygon concept (const version)
+\ingroup const_concepts
+\details The ConstPolygon concept check the same as the Polygon concept,
+but does not check write access.
+*/
+template <typename Geometry>
+class ConstPolygon
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+
+    typedef typename point_type<Geometry>::type point_type;
+    typedef typename ring_type<Geometry>::type ring_type;
+    typedef typename interior_type<Geometry>::type interior_type;
+
+    BOOST_CONCEPT_ASSERT( (concept::ConstPoint<point_type>) );
+    BOOST_CONCEPT_ASSERT( (concept::ConstRing<ring_type>) );
+
+    BOOST_CONCEPT_ASSERT( (boost::RandomAccessRangeConcept<interior_type>) );
+
+    struct checker
+    {
+        static inline void apply()
+        {
+            Geometry* poly;
+            ring_type const& ce = exterior_ring(*poly);
+            interior_type const& ci = interior_rings(*poly);
+
+            boost::ignore_unused_variable_warning(ce);
+            boost::ignore_unused_variable_warning(ci);
+            boost::ignore_unused_variable_warning(poly);
+        }
+    };
+
+
+public:
+
+    BOOST_CONCEPT_USAGE(ConstPolygon)
+    {
+        checker::apply();
+    }
+#endif
+};
+
+}} // namespace ggl::concept
+
+#endif // GGL_GEOMETRIES_CONCEPTS_POLYGON_CONCEPT_HPP
Added: sandbox/ggl/formal_review/boost/ggl/geometries/concepts/ring_concept.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/geometries/concepts/ring_concept.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,103 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_GEOMETRIES_CONCEPTS_RING_CONCEPT_HPP
+#define GGL_GEOMETRIES_CONCEPTS_RING_CONCEPT_HPP
+
+
+#include <boost/concept_check.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/point_type.hpp>
+
+#include <ggl/geometries/concepts/point_concept.hpp>
+
+#include <ggl/geometries/concepts/detail/check_clear.hpp>
+#include <ggl/geometries/concepts/detail/check_append.hpp>
+
+
+namespace ggl { namespace concept {
+
+
+/*!
+\brief ring concept
+\ingroup concepts
+\par Formal definition:
+The ring concept is defined as following:
+- there must be a specialization of traits::tag defining ring_tag as type
+- it must behave like a Boost.Range
+- there can optionally be a specialization of traits::point_order defining the
+  order or orientation of its points, clockwise or counterclockwise.
+- either it can behave like the std library, having pushback
+- or it can implement a mechanism for clearing and adding points.
+  This is the same as the for the concept Linestring, and described there.
+
+\note to fulfil the concepts, no traits class has to be specialized to
+define the point type. The point type is taken using boost::range_value<X>::type
+*/
+template <typename Geometry>
+class Ring
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+    typedef typename point_type<Geometry>::type point_type;
+
+    BOOST_CONCEPT_ASSERT( (concept::Point<point_type>) );
+    BOOST_CONCEPT_ASSERT( (boost::RandomAccessRangeConcept<Geometry>) );
+
+
+public :
+
+    BOOST_CONCEPT_USAGE(Ring)
+    {
+        // Check if it can be modified
+        static const bool use_std = traits::use_std
+            <
+                typename boost::remove_const<Geometry>::type
+            >::value;
+
+        Geometry* ring;
+        detail::check_clear<Geometry, use_std>::apply(*ring);
+
+        point_type* p;
+        detail::check_append<Geometry, point_type, use_std>::apply(*ring, *p);
+    }
+#endif
+};
+
+
+/*!
+\brief (linear) ring concept (const version)
+\ingroup const_concepts
+\details The ConstLinearRing concept check the same as the Geometry concept,
+but does not check write access.
+*/
+template <typename Geometry>
+class ConstRing
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+    typedef typename point_type<Geometry>::type point_type;
+
+    BOOST_CONCEPT_ASSERT( (concept::ConstPoint<point_type>) );
+    BOOST_CONCEPT_ASSERT( (boost::RandomAccessRangeConcept<Geometry>) );
+
+
+public :
+
+    BOOST_CONCEPT_USAGE(ConstRing)
+    {
+    }
+#endif
+};
+
+}} // namespace ggl::concept
+
+
+#endif // GGL_GEOMETRIES_CONCEPTS_RING_CONCEPT_HPP
Added: sandbox/ggl/formal_review/boost/ggl/geometries/concepts/segment_concept.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/geometries/concepts/segment_concept.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,133 @@
+// Generic Geometry Library
+//
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_GEOMETRIES_CONCEPTS_SEGMENT_CONCEPT_HPP
+#define GGL_GEOMETRIES_CONCEPTS_SEGMENT_CONCEPT_HPP
+
+
+#include <boost/concept_check.hpp>
+
+#include <ggl/geometries/concepts/point_concept.hpp>
+
+
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/point_type.hpp>
+
+
+
+namespace ggl { namespace concept {
+
+
+/*!
+\brief segment concept
+\ingroup concepts
+\par Formal definition:
+The segment concept is defined as following:
+- there must be a specialization of traits::tag defining segment_tag as type
+- there must be a specialization of traits::point_type to define the
+  underlying point type (even if it does not consist of points, it should define
+  this type, to indicate the points it can work with)
+- there must be a specialization of traits::indexed_access, per index
+  and per dimension, with two functions:
+  - get to get a coordinate value
+  - set to set a coordinate value (this one is not checked for ConstSegment)
+
+\note The segment concept is similar to the box concept, defining another tag.
+However, the box concept assumes the index as min_corner, max_corner, while
+for the segment concept there is no assumption.
+*/
+template <typename Geometry>
+class Segment
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+    typedef typename point_type<Geometry>::type point_type;
+
+    BOOST_CONCEPT_ASSERT( (concept::Point<point_type>) );
+
+
+    template <size_t Index, size_t Dimension, size_t DimensionCount>
+    struct dimension_checker
+    {
+        static void apply()
+        {
+            Geometry* s;
+            ggl::set<Index, Dimension>(*s, ggl::get<Index, Dimension>(*s));
+            dimension_checker<Index, Dimension + 1, DimensionCount>::apply();
+        }
+    };
+
+    template <size_t Index, size_t DimensionCount>
+    struct dimension_checker<Index, DimensionCount, DimensionCount>
+    {
+        static void apply() {}
+    };
+
+public :
+
+    BOOST_CONCEPT_USAGE(Segment)
+    {
+        static const size_t n = dimension<point_type>::type::value;
+        dimension_checker<0, 0, n>::apply();
+        dimension_checker<1, 0, n>::apply();
+    }
+#endif
+};
+
+
+/*!
+\brief Segment concept (const version)
+\ingroup const_concepts
+\details The ConstSegment concept verifies the same as the Segment concept,
+but does not verify write access.
+*/
+template <typename Geometry>
+class ConstSegment
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+    typedef typename point_type<Geometry>::type point_type;
+    typedef typename coordinate_type<Geometry>::type coordinate_type;
+
+    BOOST_CONCEPT_ASSERT( (concept::ConstPoint<point_type>) );
+
+
+    template <size_t Index, size_t Dimension, size_t DimensionCount>
+    struct dimension_checker
+    {
+        static void apply()
+        {
+            const Geometry* s = 0;
+            coordinate_type coord(ggl::get<Index, Dimension>(*s));
+            boost::ignore_unused_variable_warning(coord);
+            dimension_checker<Index, Dimension + 1, DimensionCount>::apply();
+        }
+    };
+
+    template <size_t Index, size_t DimensionCount>
+    struct dimension_checker<Index, DimensionCount, DimensionCount>
+    {
+        static void apply() {}
+    };
+
+public :
+
+    BOOST_CONCEPT_USAGE(ConstSegment)
+    {
+        static const size_t n = dimension<point_type>::type::value;
+        dimension_checker<0, 0, n>::apply();
+        dimension_checker<1, 0, n>::apply();
+    }
+#endif
+};
+
+
+}} // namespace ggl::concept
+
+
+#endif // GGL_GEOMETRIES_CONCEPTS_SEGMENT_CONCEPT_HPP
Added: sandbox/ggl/formal_review/boost/ggl/geometries/geometries.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/geometries/geometries.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,35 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_GEOMETRIES_HPP
+#define GGL_GEOMETRIES_HPP
+
+
+/*!
+\defgroup geometries geometries: geometries provided by default
+\details The GGL can be used with the geometry classes provided by the library,
+and with custom geometries registered by traits classes or registration
+macros.
+
+This documentation page refers to the geometry classes provided by the library.
+
+*/
+
+#include <ggl/geometries/adapted/c_array.hpp>
+#include <ggl/geometries/adapted/tuple.hpp>
+
+#include <ggl/geometries/point.hpp>
+#include <ggl/geometries/point_xy.hpp>
+#include <ggl/geometries/linear_ring.hpp>
+#include <ggl/geometries/linestring.hpp>
+#include <ggl/geometries/polygon.hpp>
+
+#include <ggl/geometries/box.hpp>
+#include <ggl/geometries/segment.hpp>
+
+#endif // GGL_GEOMETRIES_HPP
Added: sandbox/ggl/formal_review/boost/ggl/geometries/linear_ring.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/geometries/linear_ring.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,94 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_GEOMETRIES_LINEAR_RING_HPP
+#define GGL_GEOMETRIES_LINEAR_RING_HPP
+
+#include <memory>
+#include <vector>
+
+#include <boost/concept/assert.hpp>
+
+#include <ggl/core/tag.hpp>
+#include <ggl/core/tags.hpp>
+#include <ggl/core/point_order.hpp>
+
+#include <ggl/geometries/concepts/point_concept.hpp>
+
+
+namespace ggl
+{
+
+/*!
+    \brief A linear_ring (linear linear_ring) is a closed line which should not be selfintersecting
+    \ingroup geometries
+    \tparam P point type
+    \tparam V optional container type, for example std::vector, std::list, std::deque
+    \tparam A optional container-allocator-type
+*/
+template
+<
+    typename P,
+    template<typename, typename> class V = std::vector,
+    bool ClockWise = true,
+    template<typename> class A = std::allocator
+>
+class linear_ring : public V<P, A<P> >
+{
+    BOOST_CONCEPT_ASSERT( (concept::Point<P>) );
+};
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+template
+<
+    typename P,
+    template<typename, typename> class V,
+    bool ClockWise,
+    template<typename> class A
+>
+struct tag< linear_ring<P, V, ClockWise, A> >
+{
+    typedef ring_tag type;
+};
+
+
+template
+<
+    typename P,
+    template<typename, typename> class V,
+    template<typename> class A
+>
+struct point_order< linear_ring<P, V, false, A> >
+{
+    static const order_selector value = counterclockwise;
+};
+
+
+template
+<
+    typename P,
+    template<typename, typename> class V,
+    template<typename> class A
+>
+struct point_order< linear_ring<P, V, true, A> >
+{
+    static const order_selector value = clockwise;
+};
+
+
+
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+} // namespace ggl
+
+#endif // GGL_GEOMETRIES_LINEAR_RING_HPP
Added: sandbox/ggl/formal_review/boost/ggl/geometries/linestring.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/geometries/linestring.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,69 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_GEOMETRIES_LINESTRING_HPP
+#define GGL_GEOMETRIES_LINESTRING_HPP
+
+#include <memory>
+#include <vector>
+
+#include <boost/concept/assert.hpp>
+#include <boost/range/functions.hpp>
+
+#include <ggl/core/tag.hpp>
+#include <ggl/core/tags.hpp>
+
+#include <ggl/geometries/concepts/point_concept.hpp>
+
+
+namespace ggl
+{
+
+/*!
+    \brief A linestring (named so by OGC) is a collection (default a vector) of points.
+    \ingroup geometries
+    \tparam P point type
+    \tparam V optional container type, for example std::vector, std::list, std::deque
+    \tparam A optional container-allocator-type
+    (see http://accu.org/index.php/journals/427#ftn.d0e249 )
+    \par Concepts:
+    All algorithms work on ranges, based on a container with point types fulfilling
+    the point concepts. They will take linestring, but also vector, std::pair, or other containers.
+*/
+template
+<
+    typename P,
+    template<typename,typename> class V = std::vector,
+    template<typename> class A = std::allocator
+>
+class linestring : public V<P, A<P> >
+{
+    BOOST_CONCEPT_ASSERT( (concept::Point<P>) );
+};
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+template
+<
+    typename P,
+    template<typename,typename> class V,
+    template<typename> class A
+>
+struct tag<linestring<P, V, A> >
+{
+    typedef linestring_tag type;
+};
+} // namespace traits
+
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+} // namespace ggl
+
+#endif // GGL_GEOMETRIES_LINESTRING_HPP
Added: sandbox/ggl/formal_review/boost/ggl/geometries/point.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/geometries/point.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,154 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_GEOMETRIES_POINT_HPP
+#define GGL_GEOMETRIES_POINT_HPP
+
+#include <cstddef>
+
+#include <boost/mpl/int.hpp>
+#include <boost/static_assert.hpp>
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/coordinate_type.hpp>
+#include <ggl/core/coordinate_system.hpp>
+#include <ggl/core/coordinate_dimension.hpp>
+#include <ggl/util/math.hpp>
+
+namespace ggl
+{
+
+/*!
+    \brief Basic point class, having coordinates defined in a neutral way
+    \ingroup geometries
+    \tparam T numeric type, for example double, float, int
+    \tparam D coordinate dimension as number of coordinates, for example 2
+    \tparam C coordinate system, for example cs::cartesian
+*/
+template<typename T, std::size_t D, typename C>
+class point
+{
+public:
+
+    // Concept typedefs and members
+    typedef T coordinate_type;
+    typedef C coordinate_system;
+
+    static const std::size_t coordinate_count = D;
+
+    /// Default constructor, no initialization at all
+    inline point()
+    {}
+
+    /// Constructs with one, or optionally two or three values
+    inline point(T const& v0, T const& v1 = 0, T const& v2 = 0)
+    {
+        if (D >= 1) m_values[0] = v0;
+        if (D >= 2) m_values[1] = v1;
+        if (D >= 3) m_values[2] = v2;
+    }
+
+
+    /// Compile time access to coordinate values
+    template <std::size_t K>
+    inline T const& get() const
+    {
+        BOOST_STATIC_ASSERT(K < D);
+        return m_values[K];
+    }
+
+    template <std::size_t K>
+    inline void set(T value)
+    {
+        BOOST_STATIC_ASSERT(K < D);
+        m_values[K] = value;
+    }
+
+
+private:
+
+    T m_values[D];
+};
+
+
+// Adapt the point to the concept
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+template
+<
+    typename CoordinateType,
+    std::size_t DimensionCount,
+    typename CoordinateSystem
+>
+struct tag<point<CoordinateType, DimensionCount, CoordinateSystem> >
+{
+    typedef point_tag type;
+};
+
+template
+<
+    typename CoordinateType,
+    std::size_t DimensionCount,
+    typename CoordinateSystem
+>
+struct coordinate_type<point<CoordinateType, DimensionCount, CoordinateSystem> >
+{
+    typedef CoordinateType type;
+};
+
+template
+<
+    typename CoordinateType,
+    std::size_t DimensionCount,
+    typename CoordinateSystem
+>
+struct coordinate_system<point<CoordinateType, DimensionCount, CoordinateSystem> >
+{
+    typedef CoordinateSystem type;
+};
+
+template
+<
+    typename CoordinateType,
+    std::size_t DimensionCount,
+    typename CoordinateSystem
+>
+struct dimension<point<CoordinateType, DimensionCount, CoordinateSystem> >
+    : boost::mpl::int_<DimensionCount>
+{};
+
+template
+<
+    typename CoordinateType,
+    std::size_t DimensionCount,
+    typename CoordinateSystem,
+    std::size_t Dimension
+>
+struct access<point<CoordinateType, DimensionCount, CoordinateSystem>, Dimension>
+{
+    static inline CoordinateType get(
+        point<CoordinateType, DimensionCount, CoordinateSystem> const& p)
+    {
+        return p.template get<Dimension>();
+    }
+
+    static inline void set(
+        point<CoordinateType, DimensionCount, CoordinateSystem>& p,
+        CoordinateType const& value)
+    {
+        p.template set<Dimension>(value);
+    }
+};
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+} // namespace ggl
+
+#endif // GGL_GEOMETRIES_POINT_HPP
Added: sandbox/ggl/formal_review/boost/ggl/geometries/point_xy.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/geometries/point_xy.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,104 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_GEOMETRIES_POINT_XY_HPP
+#define GGL_GEOMETRIES_POINT_XY_HPP
+
+#include <cstddef>
+
+#include <boost/mpl/int.hpp>
+
+#include <ggl/core/cs.hpp>
+#include <ggl/geometries/point.hpp>
+
+namespace ggl
+{
+
+/*!
+    \brief 2D point in Cartesian coordinate system
+    \ingroup geometries
+    \tparam T numeric type, arguments can be, for example, double, float, int
+*/
+template<typename T, typename C = cs::cartesian>
+class point_xy : public point<T, 2, C>
+{
+public:
+
+    /// Default constructor, does not initialize anything
+    inline point_xy() : point<T, 2, C>() {}
+
+    /// Constructor with x/y values
+    inline point_xy(T const& x, T const& y) : point<T, 2, C>(x, y) {}
+
+    /// Get x-value
+    inline T const& x() const
+    { return this->template get<0>(); }
+
+    /// Get y-value
+    inline T const& y() const
+    { return this->template get<1>(); }
+
+    /// Set x-value
+    inline void x(T const& v)
+    { this->template set<0>(v); }
+
+    /// Set y-value
+    inline void y(T const& v)
+    { this->template set<1>(v); }
+};
+
+// Adapt the point_xy to the concept
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+template <typename CoordinateType, typename CoordinateSystem>
+struct tag<point_xy<CoordinateType, CoordinateSystem> >
+{
+    typedef point_tag type;
+};
+
+template<typename CoordinateType, typename CoordinateSystem>
+struct coordinate_type<point_xy<CoordinateType, CoordinateSystem> >
+{
+    typedef CoordinateType type;
+};
+
+template<typename CoordinateType, typename CoordinateSystem>
+struct coordinate_system<point_xy<CoordinateType, CoordinateSystem> >
+{
+    typedef CoordinateSystem type;
+};
+
+template<typename CoordinateType, typename CoordinateSystem>
+struct dimension<point_xy<CoordinateType, CoordinateSystem> >
+    : boost::mpl::int_<2>
+{};
+
+template<typename CoordinateType, typename CoordinateSystem, std::size_t Dimension>
+struct access<point_xy<CoordinateType, CoordinateSystem>, Dimension >
+{
+    static inline CoordinateType get(
+        point_xy<CoordinateType, CoordinateSystem> const& p)
+    {
+        return p.template get<Dimension>();
+    }
+
+    static inline void set(point_xy<CoordinateType, CoordinateSystem>& p,
+        CoordinateType const& value)
+    {
+        p.template set<Dimension>(value);
+    }
+};
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+} // namespace ggl
+
+#endif // GGL_GEOMETRIES_POINT_XY_HPP
Added: sandbox/ggl/formal_review/boost/ggl/geometries/polygon.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/geometries/polygon.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,189 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_GEOMETRIES_POLYGON_HPP
+#define GGL_GEOMETRIES_POLYGON_HPP
+
+#include <memory>
+#include <vector>
+
+#include <boost/concept/assert.hpp>
+
+#include <ggl/core/exterior_ring.hpp>
+#include <ggl/core/interior_rings.hpp>
+#include <ggl/core/point_type.hpp>
+#include <ggl/core/ring_type.hpp>
+#include <ggl/geometries/concepts/point_concept.hpp>
+#include <ggl/geometries/linear_ring.hpp>
+
+namespace ggl
+{
+
+/*!
+    \brief The \b polygon contains an outer ring and zero or more inner rings.
+    \ingroup geometries
+    \tparam P point type
+    \tparam PointList optional container type for points,
+                for example std::vector, std::list, std::deque
+    \tparam RingList optional container type for inner rings,
+                for example std::vector, std::list, std::deque
+    \tparam ClockWise optional parameter, true for clockwise direction,
+                false for CounterClockWise direction
+    \tparam PointAlloc container-allocator-type
+    \tparam RingAlloc container-allocator-type
+    \note The container collecting the points in the rings can be different
+        from the container collecting the inner rings. They all default to vector.
+*/
+template
+<
+    typename Point,
+    template<typename, typename> class PointList = std::vector,
+    template<typename, typename> class RingList = std::vector,
+    bool ClockWise = true,
+    template<typename> class PointAlloc = std::allocator,
+    template<typename> class RingAlloc = std::allocator
+>
+class polygon
+{
+    BOOST_CONCEPT_ASSERT( (concept::Point<Point>) );
+
+public:
+
+    // Member types
+    typedef Point point_type;
+    typedef linear_ring<Point, PointList, ClockWise, PointAlloc> ring_type;
+    typedef RingList<ring_type , RingAlloc<ring_type > > inner_container_type;
+
+    inline ring_type const& outer() const { return m_outer; }
+    inline inner_container_type const& inners() const { return m_inners; }
+
+    inline ring_type& outer() { return m_outer; }
+    inline inner_container_type & inners() { return m_inners; }
+
+    /// Utility method, clears outer and inner rings
+    inline void clear()
+    {
+        m_outer.clear();
+        m_inners.clear();
+    }
+
+private:
+
+    ring_type m_outer;
+    inner_container_type m_inners;
+};
+
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+template
+<
+    typename Point,
+    template<typename, typename> class PointList,
+    template<typename, typename> class RingList,
+    bool ClockWise,
+    template<typename> class PointAlloc,
+    template<typename> class RingAlloc
+>
+struct tag<polygon<Point, PointList, RingList, ClockWise, PointAlloc, RingAlloc> >
+{
+    typedef polygon_tag type;
+};
+
+template
+<
+    typename Point,
+    template<typename, typename> class PointList,
+    template<typename, typename> class RingList,
+    bool ClockWise,
+    template<typename> class PointAlloc,
+    template<typename> class RingAlloc
+>
+struct ring_type<polygon<Point, PointList, RingList, ClockWise, PointAlloc, RingAlloc> >
+{
+    typedef typename polygon
+        <
+            Point, PointList, RingList, ClockWise, PointAlloc, RingAlloc
+        >::ring_type type;
+};
+
+template
+<
+    typename Point,
+    template<typename, typename> class PointList,
+    template<typename, typename> class RingList,
+    bool ClockWise,
+    template<typename> class PointAlloc,
+    template<typename> class RingAlloc
+>
+struct interior_type< polygon<Point, PointList, RingList, ClockWise, PointAlloc, RingAlloc> >
+{
+    typedef typename polygon
+        <
+            Point, PointList, RingList, ClockWise, PointAlloc, RingAlloc
+        >::inner_container_type type;
+};
+
+template
+<
+    typename Point,
+    template<typename, typename> class PointList,
+    template<typename, typename> class RingList,
+    bool ClockWise,
+    template<typename> class PointAlloc,
+    template<typename> class RingAlloc
+>
+struct exterior_ring< polygon<Point, PointList, RingList, ClockWise, PointAlloc, RingAlloc> >
+{
+    typedef polygon<Point, PointList, RingList, ClockWise, PointAlloc, RingAlloc> polygon_type;
+
+    static inline typename polygon_type::ring_type& get(polygon_type& p)
+    {
+        return p.outer();
+    }
+
+    static inline typename polygon_type::ring_type const & get(polygon_type const& p)
+    {
+        return p.outer();
+    }
+};
+
+template
+<
+    typename Point,
+    template<typename, typename> class PointList,
+    template<typename, typename> class RingList,
+    bool ClockWise,
+    template<typename> class PointAlloc,
+    template<typename> class RingAlloc
+>
+struct interior_rings< polygon<Point, PointList, RingList, ClockWise, PointAlloc, RingAlloc> >
+{
+    typedef polygon<Point, PointList, RingList, ClockWise, PointAlloc, RingAlloc> polygon_type;
+
+    static inline typename polygon_type::inner_container_type& get(
+                    polygon_type& p)
+    {
+        return p.inners();
+    }
+
+    static inline typename polygon_type::inner_container_type const& get(
+                    polygon_type const& p)
+    {
+        return p.inners();
+    }
+};
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+} // namespace ggl
+
+#endif // GGL_GEOMETRIES_POLYGON_HPP
Added: sandbox/ggl/formal_review/boost/ggl/geometries/register/box.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/geometries/register/box.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,124 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_GEOMETRIES_REGISTER_BOX_HPP
+#define GGL_GEOMETRIES_REGISTER_BOX_HPP
+
+
+#ifndef DOXYGEN_NO_SPECIALIZATIONS
+
+
+#define GEOMETRY_DETAIL_SPECIALIZE_BOX_ACCESS(Box, Point, MinCorner, MaxCorner) \
+template <size_t D> \
+struct indexed_access<Box, min_corner, D> \
+{ \
+    typedef typename coordinate_type<Point>::type ct; \
+    static inline ct get(Box const& b) \
+    { return ggl::get<D>(b. MinCorner);  } \
+    static inline void set(Box& b, ct const& value) \
+    { ggl::set<D>(b. MinCorner, value);  } \
+}; \
+template <size_t D> \
+struct indexed_access<Box, max_corner, D> \
+{ \
+    typedef typename coordinate_type<Point>::type ct; \
+    static inline ct get(Box const& b) \
+    { return ggl::get<D>(b. MaxCorner);  } \
+    static inline void set(Box& b, ct const& value) \
+    { ggl::set<D>(b. MaxCorner, value);  } \
+};
+
+
+#define GEOMETRY_DETAIL_SPECIALIZE_BOX_ACCESS_TEMPLATIZED(Box, MinCorner, MaxCorner) \
+template <typename P, size_t D> \
+struct indexed_access<Box<P>, min_corner, D> \
+{ \
+    typedef typename coordinate_type<P>::type ct; \
+    static inline ct get(Box<P> const& b) \
+    { return ggl::get<D>(b. MinCorner);  } \
+    static inline void set(Box<P>& b, ct const& value) \
+    { ggl::set<D>(b. MinCorner, value);  } \
+}; \
+template <typename P, size_t D> \
+struct indexed_access<Box<P>, max_corner, D> \
+{ \
+    typedef typename coordinate_type<P>::type ct; \
+    static inline ct get(Box<P> const& b) \
+    { return ggl::get<D>(b. MaxCorner);  } \
+    static inline void set(Box<P>& b, ct const& value) \
+    { ggl::set<D>(b. MaxCorner, value);  } \
+};
+
+
+#define GEOMETRY_DETAIL_SPECIALIZE_BOX_ACCESS_4VALUES(Box, Point, Left, Bottom, Right, Top) \
+template <> struct indexed_access<Box, min_corner, 0> \
+{ \
+    typedef coordinate_type<Point>::type ct; \
+    static inline ct get(Box const& b) { return b. Left;  } \
+    static inline void set(Box& b, ct const& value) { b. Left = value; } \
+}; \
+template <> struct indexed_access<Box, min_corner, 1> \
+{ \
+    typedef coordinate_type<Point>::type ct; \
+    static inline ct get(Box const& b) { return b. Bottom;  } \
+    static inline void set(Box& b, ct const& value) { b. Bottom = value; } \
+}; \
+template <> struct indexed_access<Box, max_corner, 0> \
+{ \
+    typedef coordinate_type<Point>::type ct; \
+    static inline ct get(Box const& b) { return b. Right;  } \
+    static inline void set(Box& b, ct const& value) { b. Right = value; } \
+}; \
+template <> struct indexed_access<Box, max_corner, 1> \
+{ \
+    typedef coordinate_type<Point>::type ct; \
+    static inline ct get(Box const& b) { return b. Top; } \
+    static inline void set(Box& b, ct const& value) { b. Top = value; } \
+};
+
+
+
+
+#define GEOMETRY_DETAIL_SPECIALIZE_BOX_TRAITS(Box, PointType) \
+    template<> struct tag<Box > { typedef box_tag type; }; \
+    template<> struct point_type<Box > { typedef PointType type; };
+
+#define GEOMETRY_DETAIL_SPECIALIZE_BOX_TRAITS_TEMPLATIZED(Box) \
+    template<typename P> struct tag<Box<P> > { typedef box_tag type; }; \
+    template<typename P> struct point_type<Box<P> > { typedef P type; };
+
+#endif // DOXYGEN_NO_SPECIALIZATIONS
+
+
+
+#define GEOMETRY_REGISTER_BOX(Box, PointType, MinCorner, MaxCorner) \
+namespace ggl { namespace traits {  \
+    GEOMETRY_DETAIL_SPECIALIZE_BOX_TRAITS(Box, PointType) \
+    GEOMETRY_DETAIL_SPECIALIZE_BOX_ACCESS(Box, PointType, MinCorner, MaxCorner) \
+}}
+
+
+#define GEOMETRY_REGISTER_BOX_TEMPLATIZED(Box, MinCorner, MaxCorner) \
+namespace ggl { namespace traits {  \
+    GEOMETRY_DETAIL_SPECIALIZE_BOX_TRAITS_TEMPLATIZED(Box) \
+    GEOMETRY_DETAIL_SPECIALIZE_BOX_ACCESS_TEMPLATIZED(Box, MinCorner, MaxCorner) \
+}}
+
+#define GEOMETRY_REGISTER_BOX_2D_4VALUES(Box, PointType, Left, Bottom, Right, Top) \
+namespace ggl { namespace traits {  \
+    GEOMETRY_DETAIL_SPECIALIZE_BOX_TRAITS(Box, PointType) \
+    GEOMETRY_DETAIL_SPECIALIZE_BOX_ACCESS_4VALUES(Box, PointType, Left, Bottom, Right, Top) \
+}}
+
+
+
+// CONST versions are for boxes probably not that common. Postponed.
+
+
+#endif // GGL_GEOMETRIES_REGISTER_BOX_HPP
Added: sandbox/ggl/formal_review/boost/ggl/geometries/register/linestring.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/geometries/register/linestring.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,25 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_GEOMETRIES_REGISTER_LINESTRING_HPP
+#define GGL_GEOMETRIES_REGISTER_LINESTRING_HPP
+
+
+#include <ggl/core/tag.hpp>
+#include <ggl/core/tags.hpp>
+
+
+#define GEOMETRY_REGISTER_LINESTRING(Linestring) \
+namespace ggl { namespace traits {  \
+    template<> struct tag<Linestring> { typedef linestring_tag type; }; \
+}}
+
+
+
+#endif // GGL_GEOMETRIES_REGISTER_LINESTRING_HPP
Added: sandbox/ggl/formal_review/boost/ggl/geometries/register/point.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/geometries/register/point.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,158 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_GEOMETRIES_REGISTER_POINT_HPP
+#define GGL_GEOMETRIES_REGISTER_POINT_HPP
+
+
+
+// This file implements a "macro party", 
+// for registration of custom geometry types
+
+#ifndef DOXYGEN_NO_SPECIALIZATIONS
+
+// Starting point, specialize basic traits necessary to register a point
+// (the 'accessor' is technically not specialization but definition, specialized in another macro)
+#define GEOMETRY_DETAIL_SPECIALIZE_POINT_TRAITS(Point, Dim, CoordinateType, CoordinateSystem) \
+    template<> struct tag<Point> { typedef point_tag type; }; \
+    template<> struct dimension<Point> : boost::mpl::int_<Dim> {}; \
+    template<> struct coordinate_type<Point> { typedef CoordinateType type; }; \
+    template<> struct coordinate_system<Point> { typedef CoordinateSystem type; }; \
+    template<std::size_t Dimension> struct Point##accessor {};
+
+
+// Non Const version
+#define GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS(Point, CoordinateType) \
+    template<std::size_t Dimension> struct access<Point, Dimension> { \
+        static inline CoordinateType get(Point const& p) \
+        { return Point##accessor<Dimension>::get(p); } \
+        static inline void set(Point& p, CoordinateType const& value) \
+        { Point##accessor<Dimension>::set(p, value); } \
+    };
+
+// Const version
+#define GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS_CONST(Point, CoordinateType) \
+    template<std::size_t Dimension> struct access<Point, Dimension> { \
+        static inline CoordinateType get(Point const& p) \
+        { return Point##accessor<Dimension>::get(p); } \
+    };
+
+
+
+
+// Specialize the point-specific-accessor class, declared below, per dimension
+#define GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESSOR(Point, Dim, CoordinateType, Get, Set) \
+    template<> struct Point##accessor< Dim > \
+    { \
+        static inline CoordinateType get(Point const& p) { return p. Get; } \
+        static inline void set(Point& p, CoordinateType const& value) { p. Set = value; } \
+    };
+
+
+// Const version
+#define GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESSOR_CONST(Point, Dim, CoordinateType, Get) \
+    template<> struct Point##accessor< Dim > \
+    { \
+        static inline CoordinateType get(Point const& p) \
+        { return p. Get; } \
+    };
+
+
+// Get/set version
+#define GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESSOR_GET_SET(Point, Dim, CoordinateType, Get, Set) \
+    template<> struct Point##accessor< Dim > \
+    { \
+        static inline CoordinateType get(Point const& p) \
+        { return  p. Get (); } \
+        static inline void set(Point& p, CoordinateType const& value) \
+        { p. Set ( value ); } \
+    };
+
+
+
+#define GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS_2D(Point, CoordinateType, Get0, Get1, Set0, Set1) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESSOR(Point, 0, CoordinateType, Get0, Set0) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESSOR(Point, 1, CoordinateType, Get1, Set1)
+
+#define GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS_3D(Point, CoordinateType, Get0, Get1, Get2, Set0, Set1, Set2) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESSOR(Point, 0, CoordinateType, Get0, Set0) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESSOR(Point, 1, CoordinateType, Get1, Set1) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESSOR(Point, 2, CoordinateType, Get2, Set2)
+
+// Const versions
+#define GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS_CONST_2D(Point, CoordinateType, Get0, Get1) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESSOR_CONST(Point, 0, CoordinateType, Get0) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESSOR_CONST(Point, 1, CoordinateType, Get1)
+
+#define GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS_CONST_3D(Point, CoordinateType, Get0, Get1, Get2) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESSOR_CONST(Point, 0, CoordinateType, Get0) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESSOR_CONST(Point, 1, CoordinateType, Get1) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESSOR_CONST(Point, 2, CoordinateType, Get2)
+
+#endif // DOXYGEN_NO_SPECIALIZATIONS
+
+
+
+// Library user macro to register a custom 2D point
+#define GEOMETRY_REGISTER_POINT_2D(Point, CoordinateType, CoordinateSystem, Field0, Field1) \
+namespace ggl { namespace traits {  \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_TRAITS(Point, 2, CoordinateType, CoordinateSystem) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS(Point, CoordinateType) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS_2D(Point, CoordinateType, Field0, Field1, Field0, Field1) \
+}}
+
+// Library user macro to register a custom 3D point
+#define GEOMETRY_REGISTER_POINT_3D(Point, CoordinateType, CoordinateSystem, Field0, Field1, Field2) \
+namespace ggl { namespace traits {  \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_TRAITS(Point, 3, CoordinateType, CoordinateSystem) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS(Point, CoordinateType) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS_3D(Point, CoordinateType, Field0, Field1, Field2, Field0, Field1, Field2) \
+}}
+
+
+
+// Library user macro to register a custom 2D point (CONST version)
+#define GEOMETRY_REGISTER_POINT_2D_CONST(Point, CoordinateType, CoordinateSystem, Field0, Field1) \
+namespace ggl { namespace traits {  \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_TRAITS(Point, 2, CoordinateType, CoordinateSystem) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS_CONST(Point, CoordinateType) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS_CONST_2D(Point, CoordinateType, Field0, Field1) \
+}}
+
+// Library user macro to register a custom 3D point (CONST version)
+#define GEOMETRY_REGISTER_POINT_3D_CONST(Point, CoordinateType, CoordinateSystem, Field0, Field1, Field2) \
+namespace ggl { namespace traits {  \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_TRAITS(Point, 3, CoordinateType, CoordinateSystem) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS_CONST(Point, CoordinateType) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS_CONST_3D(Point, CoordinateType, Field0, Field1, Field2) \
+}}
+
+
+// Library user macro to register a custom 2D point (having separate get/set methods)
+#define GEOMETRY_REGISTER_POINT_2D_GET_SET(Point, CoordinateType, CoordinateSystem, Get0, Get1, Set0, Set1) \
+namespace ggl { namespace traits {  \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_TRAITS(Point, 2, CoordinateType, CoordinateSystem) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS(Point, CoordinateType) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESSOR_GET_SET(Point, 0, CoordinateType, Get0, Set0) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESSOR_GET_SET(Point, 1, CoordinateType, Get1, Set1) \
+}}
+
+
+// Library user macro to register a custom 3D point (having separate get/set methods)
+#define GEOMETRY_REGISTER_POINT_3D_GET_SET(Point, CoordinateType, CoordinateSystem, Get0, Get1, Get2, Set0, Set1, Set2) \
+namespace ggl { namespace traits {  \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_TRAITS(Point, 3, CoordinateType, CoordinateSystem) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESS(Point, CoordinateType) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESSOR_GET_SET(Point, 0, CoordinateType, Get0, Set0) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESSOR_GET_SET(Point, 1, CoordinateType, Get1, Set1) \
+    GEOMETRY_DETAIL_SPECIALIZE_POINT_ACCESSOR_GET_SET(Point, 2, CoordinateType, Get2, Set2) \
+}}
+
+
+#endif // GGL_GEOMETRIES_REGISTER_POINT_HPP
Added: sandbox/ggl/formal_review/boost/ggl/geometries/register/ring.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/geometries/register/ring.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,28 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_GEOMETRIES_REGISTER_RING_HPP
+#define GGL_GEOMETRIES_REGISTER_RING_HPP
+
+#include <ggl/core/tag.hpp>
+#include <ggl/core/tags.hpp>
+
+#define GEOMETRY_REGISTER_RING(Ring) \
+namespace ggl { namespace traits {  \
+    template<> struct tag<Ring> { typedef ring_tag type; }; \
+}}
+
+
+#define GEOMETRY_REGISTER_RING_TEMPLATIZED(Ring) \
+namespace ggl { namespace traits {  \
+    template<typename P> struct tag< Ring<P> > { typedef ring_tag type; }; \
+}}
+
+
+#endif // GGL_GEOMETRIES_REGISTER_RING_HPP
Added: sandbox/ggl/formal_review/boost/ggl/geometries/register/segment.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/geometries/register/segment.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,124 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_GEOMETRIES_REGISTER_SEGMENT_HPP
+#define GGL_GEOMETRIES_REGISTER_SEGMENT_HPP
+
+
+#ifndef DOXYGEN_NO_SPECIALIZATIONS
+
+
+#define GEOMETRY_DETAIL_SPECIALIZE_SEGMENT_ACCESS(Segment, Point, Index0, Index1) \
+template <size_t D> \
+struct indexed_access<Segment, min_corner, D> \
+{ \
+    typedef typename coordinate_type<Point>::type ct; \
+    static inline ct get(Segment const& b) \
+    { return ggl::get<D>(b. Index0);  } \
+    static inline void set(Segment& b, ct const& value) \
+    { ggl::set<D>(b. Index0, value);  } \
+}; \
+template <size_t D> \
+struct indexed_access<Segment, max_corner, D> \
+{ \
+    typedef typename coordinate_type<Point>::type ct; \
+    static inline ct get(Segment const& b) \
+    { return ggl::get<D>(b. Index1);  } \
+    static inline void set(Segment& b, ct const& value) \
+    { ggl::set<D>(b. Index1, value);  } \
+};
+
+
+#define GEOMETRY_DETAIL_SPECIALIZE_SEGMENT_ACCESS_TEMPLATIZED(Segment, Index0, Index1) \
+template <typename P, size_t D> \
+struct indexed_access<Segment<P>, min_corner, D> \
+{ \
+    typedef typename coordinate_type<P>::type ct; \
+    static inline ct get(Segment<P> const& b) \
+    { return ggl::get<D>(b. Index0);  } \
+    static inline void set(Segment<P>& b, ct const& value) \
+    { ggl::set<D>(b. Index0, value);  } \
+}; \
+template <typename P, size_t D> \
+struct indexed_access<Segment<P>, max_corner, D> \
+{ \
+    typedef typename coordinate_type<P>::type ct; \
+    static inline ct get(Segment<P> const& b) \
+    { return ggl::get<D>(b. Index1);  } \
+    static inline void set(Segment<P>& b, ct const& value) \
+    { ggl::set<D>(b. Index1, value);  } \
+};
+
+
+#define GEOMETRY_DETAIL_SPECIALIZE_SEGMENT_ACCESS_4VALUES(Segment, Point, Left, Bottom, Right, Top) \
+template <> struct indexed_access<Segment, min_corner, 0> \
+{ \
+    typedef coordinate_type<Point>::type ct; \
+    static inline ct get(Segment const& b) { return b. Left;  } \
+    static inline void set(Segment& b, ct const& value) { b. Left = value; } \
+}; \
+template <> struct indexed_access<Segment, min_corner, 1> \
+{ \
+    typedef coordinate_type<Point>::type ct; \
+    static inline ct get(Segment const& b) { return b. Bottom;  } \
+    static inline void set(Segment& b, ct const& value) { b. Bottom = value; } \
+}; \
+template <> struct indexed_access<Segment, max_corner, 0> \
+{ \
+    typedef coordinate_type<Point>::type ct; \
+    static inline ct get(Segment const& b) { return b. Right;  } \
+    static inline void set(Segment& b, ct const& value) { b. Right = value; } \
+}; \
+template <> struct indexed_access<Segment, max_corner, 1> \
+{ \
+    typedef coordinate_type<Point>::type ct; \
+    static inline ct get(Segment const& b) { return b. Top; } \
+    static inline void set(Segment& b, ct const& value) { b. Top = value; } \
+};
+
+
+
+
+#define GEOMETRY_DETAIL_SPECIALIZE_SEGMENT_TRAITS(Segment, PointType) \
+    template<> struct tag<Segment > { typedef segment_tag type; }; \
+    template<> struct point_type<Segment > { typedef PointType type; };
+
+#define GEOMETRY_DETAIL_SPECIALIZE_SEGMENT_TRAITS_TEMPLATIZED(Segment) \
+    template<typename P> struct tag<Segment<P> > { typedef segment_tag type; }; \
+    template<typename P> struct point_type<Segment<P> > { typedef P type; };
+
+#endif // DOXYGEN_NO_SPECIALIZATIONS
+
+
+
+#define GEOMETRY_REGISTER_SEGMENT(Segment, PointType, Index0, Index1) \
+namespace ggl { namespace traits {  \
+    GEOMETRY_DETAIL_SPECIALIZE_SEGMENT_TRAITS(Segment, PointType) \
+    GEOMETRY_DETAIL_SPECIALIZE_SEGMENT_ACCESS(Segment, PointType, Index0, Index1) \
+}}
+
+
+#define GEOMETRY_REGISTER_SEGMENT_TEMPLATIZED(Segment, Index0, Index1) \
+namespace ggl { namespace traits {  \
+    GEOMETRY_DETAIL_SPECIALIZE_SEGMENT_TRAITS_TEMPLATIZED(Segment) \
+    GEOMETRY_DETAIL_SPECIALIZE_SEGMENT_ACCESS_TEMPLATIZED(Segment, Index0, Index1) \
+}}
+
+#define GEOMETRY_REGISTER_SEGMENT_2D_4VALUES(Segment, PointType, Left, Bottom, Right, Top) \
+namespace ggl { namespace traits {  \
+    GEOMETRY_DETAIL_SPECIALIZE_SEGMENT_TRAITS(Segment, PointType) \
+    GEOMETRY_DETAIL_SPECIALIZE_SEGMENT_ACCESS_4VALUES(Segment, PointType, Left, Bottom, Right, Top) \
+}}
+
+
+
+// CONST versions are for segments probably not that common. Postponed.
+
+
+#endif // GGL_GEOMETRIES_REGISTER_SEGMENT_HPP
Added: sandbox/ggl/formal_review/boost/ggl/geometries/segment.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/geometries/segment.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,118 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_GEOMETRIES_SEGMENT_HPP
+#define GGL_GEOMETRIES_SEGMENT_HPP
+
+#include <cstddef>
+
+#include <boost/concept/assert.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits/is_const.hpp>
+
+#include <ggl/geometries/concepts/point_concept.hpp>
+
+namespace ggl
+{
+
+/*!
+\brief Class segment: small class containing two (templatized) point references
+\ingroup geometries
+\details From Wikipedia: In geometry, a line segment is a part of a line that is bounded
+ by two distinct end points, and contains every point on the line between its end points.
+\note The structure is like std::pair, and can often be used interchangeable.
+Difference is that it refers to points, does not have points.
+\note Like std::pair, points are public available.
+\note type is const or non const, so ggl::segment<P> or ggl::segment<const P>
+\note We cannot derive from std::pair<P&, P&> because of
+reference assignments.
+\tparam ConstOrNonConstPoint point type of the segment, maybe a point or a const point
+*/
+template<typename ConstOrNonConstPoint>
+class segment
+{
+    BOOST_CONCEPT_ASSERT( (
+        typename boost::mpl::if_
+            <
+                boost::is_const<ConstOrNonConstPoint>,
+                concept::Point<ConstOrNonConstPoint>,
+                concept::ConstPoint<ConstOrNonConstPoint>
+            >
+    ) );
+
+    typedef ConstOrNonConstPoint point_type;
+
+public:
+
+    point_type& first;
+    point_type& second;
+
+    inline segment(point_type& p1, point_type& p2)
+        : first(p1)
+        , second(p2)
+    {}
+};
+
+// Traits specializations for segment above
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+template <typename ConstOrNonConstPoint>
+struct tag<segment<ConstOrNonConstPoint> >
+{
+    typedef segment_tag type;
+};
+
+template <typename ConstOrNonConstPoint>
+struct point_type<segment<ConstOrNonConstPoint> >
+{
+    typedef ConstOrNonConstPoint type;
+};
+
+template <typename ConstOrNonConstPoint, std::size_t Dimension>
+struct indexed_access<segment<ConstOrNonConstPoint>, 0, Dimension>
+{
+    typedef segment<ConstOrNonConstPoint> segment_type;
+    typedef typename ggl::coordinate_type<segment_type>::type coordinate_type;
+
+    static inline coordinate_type get(segment_type const& s)
+    {
+        return ggl::get<Dimension>(s.first);
+    }
+
+    static inline void set(segment_type& s, coordinate_type const& value)
+    {
+        ggl::set<Dimension>(s.first, value);
+    }
+};
+
+
+template <typename ConstOrNonConstPoint, std::size_t Dimension>
+struct indexed_access<segment<ConstOrNonConstPoint>, 1, Dimension>
+{
+    typedef segment<ConstOrNonConstPoint> segment_type;
+    typedef typename ggl::coordinate_type<segment_type>::type coordinate_type;
+
+    static inline coordinate_type get(segment_type const& s)
+    {
+        return ggl::get<Dimension>(s.second);
+    }
+
+    static inline void set(segment_type& s, coordinate_type const& value)
+    {
+        ggl::set<Dimension>(s.second, value);
+    }
+};
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+} // namespace ggl
+
+#endif // GGL_GEOMETRIES_SEGMENT_HPP
Added: sandbox/ggl/formal_review/boost/ggl/ggl.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/ggl.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,63 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Copyright (c) 2009 Mateusz Loskot <mateusz_at_[hidden]>
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_GGL_HPP
+#define GGL_GGL_HPP
+
+// Shortcut to include all header files
+
+
+#include <ggl/core/cs.hpp>
+#include <ggl/core/tag.hpp>
+#include <ggl/core/tags.hpp>
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/radian_access.hpp>
+#include <ggl/core/topological_dimension.hpp>
+
+#include <ggl/core/replace_point_type.hpp>
+
+#include <ggl/arithmetic/arithmetic.hpp>
+#include <ggl/arithmetic/dot_product.hpp>
+
+#include <ggl/strategies/strategies.hpp>
+
+#include <ggl/algorithms/append.hpp>
+#include <ggl/algorithms/area.hpp>
+#include <ggl/algorithms/assign.hpp>
+#include <ggl/algorithms/centroid.hpp>
+#include <ggl/algorithms/clear.hpp>
+#include <ggl/algorithms/convert.hpp>
+#include <ggl/algorithms/convex_hull.hpp>
+#include <ggl/algorithms/correct.hpp>
+#include <ggl/algorithms/distance.hpp>
+#include <ggl/algorithms/envelope.hpp>
+#include <ggl/algorithms/for_each.hpp>
+#include <ggl/algorithms/intersection.hpp>
+#include <ggl/algorithms/intersects.hpp>
+#include <ggl/algorithms/length.hpp>
+#include <ggl/algorithms/make.hpp>
+#include <ggl/algorithms/num_points.hpp>
+#include <ggl/algorithms/perimeter.hpp>
+#include <ggl/algorithms/sectionalize.hpp>
+#include <ggl/algorithms/simplify.hpp>
+#include <ggl/algorithms/transform.hpp>
+#include <ggl/algorithms/within.hpp>
+
+// check includes all concepts
+#include <ggl/geometries/concepts/check.hpp>
+
+#include <ggl/util/copy.hpp>
+#include <ggl/util/for_each_coordinate.hpp>
+#include <ggl/util/math.hpp>
+#include <ggl/util/select_most_precise.hpp>
+#include <ggl/util/select_coordinate_type.hpp>
+#include <ggl/util/write_dsv.hpp>
+
+#endif // GGL_GGL_HPP
Added: sandbox/ggl/formal_review/boost/ggl/iterators/base.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/iterators/base.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,59 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ITERATORS_BASE_HPP
+#define GGL_ITERATORS_BASE_HPP
+
+#include <boost/iterator.hpp>
+#include <boost/iterator/iterator_adaptor.hpp>
+#include <boost/iterator/iterator_categories.hpp>
+#include <boost/mpl/if.hpp>
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace ggl { namespace detail { namespace iterators {
+
+template <typename T, typename Iterator>
+struct iterator_base :
+    public  boost::iterator_adaptor
+    <
+        T,
+        Iterator,
+        boost::use_default,
+        typename boost::mpl::if_
+        <
+            boost::is_convertible
+            <
+                typename boost::iterator_traversal<Iterator>::type,
+                boost::random_access_traversal_tag
+            >,
+            boost::bidirectional_traversal_tag,
+            boost::use_default
+        >::type
+    >
+{
+    // Define operator cast to Iterator to be able to write things like Iterator it = myit++
+    inline operator Iterator() const
+    {
+        return this->base();
+    }
+
+    /*inline bool operator==(const Iterator& other) const
+    {
+        return this->base() == other;
+    }
+    inline bool operator!=(const Iterator& other) const
+    {
+        return ! operator==(other);
+    }*/
+};
+
+}}} // namespace ggl::detail::iterators
+#endif
+
+
+#endif // GGL_ITERATORS_BASE_HPP
Added: sandbox/ggl/formal_review/boost/ggl/iterators/circular_iterator.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/iterators/circular_iterator.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,92 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ITERATORS_CIRCULAR_ITERATOR_HPP
+#define GGL_ITERATORS_CIRCULAR_ITERATOR_HPP
+
+#include <boost/iterator.hpp>
+#include <boost/iterator/iterator_adaptor.hpp>
+#include <boost/iterator/iterator_categories.hpp>
+
+#include <ggl/iterators/base.hpp>
+
+namespace ggl
+{
+
+/*!
+    \brief Iterator which goes circular through a range, starting at a point, ending at that point
+    \tparam Iterator iterator on which this class is based on
+    \ingroup iterators
+*/
+template <typename Iterator>
+struct circular_iterator :
+    public detail::iterators::iterator_base
+    <
+        circular_iterator<Iterator>,
+        Iterator
+    >
+{
+    friend class boost::iterator_core_access;
+
+    explicit inline circular_iterator(Iterator begin, Iterator end, Iterator start)
+        : m_begin(begin)
+        , m_end(end)
+        , m_start(start)
+    {
+        this->base_reference() = start;
+    }
+
+    // Constructor to indicate the end of a range, to enable e.g. std::copy
+    explicit inline circular_iterator(Iterator end)
+        : m_begin(end)
+        , m_end(end)
+        , m_start(end)
+    {
+        this->base_reference() = end;
+    }
+
+    /// Navigate to a certain position, should be in [start .. end], it at end
+    /// it will circle again.
+    inline void moveto(Iterator it)
+    {
+        this->base_reference() = it;
+        check_end();
+    }
+
+private:
+
+    inline void increment()
+    {
+        if (this->base() != m_end)
+        {
+            (this->base_reference())++;
+            check_end();
+        }
+    }
+
+    inline void check_end()
+    {
+        if (this->base() == this->m_end)
+        {
+            this->base_reference() = this->m_begin;
+        }
+
+        if (this->base() == m_start)
+        {
+            this->base_reference() = this->m_end;
+        }
+    }
+
+    Iterator m_begin;
+    Iterator m_end;
+    Iterator m_start;
+};
+
+} // namespace ggl
+
+#endif // GGL_ITERATORS_CIRCULAR_ITERATOR_HPP
Added: sandbox/ggl/formal_review/boost/ggl/iterators/ever_circling_iterator.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/iterators/ever_circling_iterator.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,86 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ITERATORS_EVER_CIRCLING_ITERATOR_HPP
+#define GGL_ITERATORS_EVER_CIRCLING_ITERATOR_HPP
+
+#include <boost/iterator.hpp>
+#include <boost/iterator/iterator_adaptor.hpp>
+#include <boost/iterator/iterator_categories.hpp>
+
+#include <ggl/iterators/base.hpp>
+
+namespace ggl
+{
+
+/*!
+    \brief Iterator which ever circles through a range
+    \tparam Iterator iterator on which this class is based on
+    \ingroup iterators
+    \details If the iterator arrives at range.end() it restarts from the
+     beginning. So it has to be stopped in another way.
+    Don't call for(....; it++) because it will turn in an endless loop
+    \note Name inspired on David Bowie's
+    "Chant Of The Ever Circling Skeletal Family"
+*/
+template <typename Iterator>
+struct ever_circling_iterator :
+    public detail::iterators::iterator_base
+    <
+        ever_circling_iterator<Iterator>,
+        Iterator
+    >
+{
+    friend class boost::iterator_core_access;
+
+    explicit inline ever_circling_iterator(Iterator begin, Iterator end)
+      : m_begin(begin)
+      , m_end(end)
+    {
+        this->base_reference() = begin;
+    }
+
+    explicit inline ever_circling_iterator(Iterator begin, Iterator end, Iterator start)
+      : m_begin(begin)
+      , m_end(end)
+    {
+        this->base_reference() = start;
+    }
+
+    /// Navigate to a certain position, should be in [start .. end], it at end
+    /// it will circle again.
+    inline void moveto(Iterator it)
+    {
+        this->base_reference() = it;
+        check_end();
+    }
+
+private:
+
+    inline void increment()
+    {
+        (this->base_reference())++;
+        check_end();
+    }
+
+    inline void check_end()
+    {
+        if (this->base() == this->m_end)
+        {
+            this->base_reference() = this->m_begin;
+        }
+    }
+
+    Iterator m_begin;
+    Iterator m_end;
+};
+
+
+} // namespace ggl
+
+#endif // GGL_ITERATORS_EVER_CIRCLING_ITERATOR_HPP
Added: sandbox/ggl/formal_review/boost/ggl/iterators/range_type.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/iterators/range_type.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,82 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ITERATORS_RANGE_TYPE_HPP
+#define GGL_ITERATORS_RANGE_TYPE_HPP
+
+#include <boost/type_traits.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+#include <ggl/core/ring_type.hpp>
+#include <ggl/core/tag.hpp>
+#include <ggl/core/tags.hpp>
+
+
+namespace ggl {
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename GeometryTag, typename Geometry>
+struct range_type
+{
+    // Even if it is not recognized, define itself as a type.
+    // This enables calling range_type over any range
+    // (not necessarily a geometry)
+
+    // Furthermore, applicable for ring/linestring
+    typedef Geometry type;
+};
+
+
+template <typename Geometry>
+struct range_type<point_tag, Geometry>
+{
+    typedef void type;
+};
+
+
+template <typename Geometry>
+struct range_type<polygon_tag, Geometry>
+{
+    typedef typename ring_type<Geometry>::type type;
+};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+
+/*!
+\brief Meta-function defining a type which is a boost-range.
+\details
+- For linestrings and rings, it defines the type itself.
+- For polygons it defines the ring type.
+- For multi-points, it defines the type itself
+- For multi-polygons and multi-linestrings, it defines the single-version
+    (so in the end the linestring and ring-type-of-multi-polygon)
+\ingroup iterators
+*/
+template <typename Geometry>
+struct range_type
+{
+    typedef typename dispatch::range_type
+        <
+            typename tag<Geometry>::type,
+            Geometry
+        >::type type;
+};
+
+
+} // namespace ggl
+
+
+#endif // GGL_ITERATORS_RANGE_TYPE_HPP
Added: sandbox/ggl/formal_review/boost/ggl/iterators/segment_iterator.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/iterators/segment_iterator.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,137 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Mateusz Loskot 2009, mateusz_at_[hidden]
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_ITERATORS_SEGMENT_ITERATOR_HPP
+#define GGL_ITERATORS_SEGMENT_ITERATOR_HPP
+
+// TODO: This is very experimental version of input iterator
+// reading collection of points as segments - proof of concept.
+// --mloskot
+
+// TODO: Move to boost::iterator_adaptor
+
+#include <iterator>
+
+#include <boost/assert.hpp>
+#include <boost/iterator.hpp>
+#include <boost/iterator/iterator_adaptor.hpp>
+#include <boost/iterator/iterator_categories.hpp>
+
+#include <ggl/algorithms/equals.hpp>
+#include <ggl/geometries/segment.hpp>
+
+namespace ggl
+{
+
+template <typename Base, typename Point>
+struct segment_iterator
+{
+    typedef Base base_type;
+    typedef Point point_type;
+    typedef typename ggl::segment<Point> segment_type;
+
+    typedef std::input_iterator_tag iterator_category;
+    typedef typename std::iterator_traits<Base>::difference_type difference_type;
+    typedef segment_type value_type;
+    typedef segment_type* pointer;
+    typedef segment_type& reference;
+
+    explicit segment_iterator(Base const& end)
+        : m_segment(p1 , p2)
+        , m_prev(end)
+        , m_it(end)
+        , m_end(end)
+    {
+    }
+
+    segment_iterator(Base const& it, Base const& end)
+        : m_segment(p1 , p2)
+        , m_prev(it)
+        , m_it(it)
+        , m_end(end)
+    {
+        if (m_it != m_end)
+        {
+            BOOST_ASSERT(m_prev != m_end);
+            ++m_it;
+        }
+    }
+
+    reference operator*()
+    {
+        BOOST_ASSERT(m_it != m_end && m_prev != m_end);
+
+        p1 = *m_prev;
+        p2 = *m_it;
+
+        return m_segment;
+    }
+
+    pointer operator->()
+    {
+        return &(operator*());
+    }
+
+    segment_iterator& operator++()
+    {
+        ++m_prev;
+        ++m_it;
+        return *this;
+    }
+
+    segment_iterator operator++(int)
+    {
+        segment_iterator it(*this);
+        ++(*this);
+        return it;
+    }
+
+    Base const& base() const { return m_it; }
+
+private:
+
+    point_type p1;
+    point_type p2;
+    segment_type m_segment;
+
+    Base m_prev;
+    Base m_it;
+    Base m_end;
+};
+
+template <typename Base, typename Point>
+bool operator==(segment_iterator<Base, Point> const& lhs,
+                segment_iterator<Base, Point> const& rhs)
+{
+    return (lhs.base() == rhs.base());
+}
+
+template <typename Base, typename Point>
+bool operator!=(segment_iterator<Base, Point> const& lhs,
+                segment_iterator<Base, Point> const& rhs)
+{
+    return (lhs.base() != rhs.base());
+}
+
+template <typename C>
+segment_iterator
+<
+    typename C::iterator,
+    typename C::value_type
+>
+make_segment_iterator(C& c)
+{
+    typedef typename C::iterator base_iterator;
+    typedef typename C::value_type point_type;
+    return segment_iterator<base_iterator, point_type>(c.begin(), c.end());
+}
+
+} // namespace ggl
+
+#endif // GGL_ITERATORS_SEGMENT_ITERATOR_HPP
Added: sandbox/ggl/formal_review/boost/ggl/multi/algorithms/area.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/multi/algorithms/area.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,47 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_ALGORITHMS_AREA_HPP
+#define GGL_MULTI_ALGORITHMS_AREA_HPP
+
+#include <ggl/algorithms/area.hpp>
+#include <ggl/multi/core/point_type.hpp>
+#include <ggl/multi/algorithms/detail/multi_sum.hpp>
+
+namespace ggl {
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+template <typename MultiGeometry, order_selector Order, typename Strategy>
+struct area<multi_polygon_tag, MultiGeometry, Order, Strategy>
+    : detail::multi_sum
+        <
+            typename Strategy::return_type, 
+            MultiGeometry, 
+            Strategy,
+            area
+                <
+                    polygon_tag,
+                    typename boost::range_value<MultiGeometry>::type, 
+                    Order, 
+                    Strategy
+                > 
+    >
+{};
+
+
+} // namespace dispatch
+#endif
+
+
+} // namespace ggl
+
+
+#endif // GGL_MULTI_ALGORITHMS_AREA_HPP
Added: sandbox/ggl/formal_review/boost/ggl/multi/algorithms/centroid.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/multi/algorithms/centroid.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,147 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_ALGORITHMS_CENTROID_HPP
+#define GGL_MULTI_ALGORITHMS_CENTROID_HPP
+
+#include <ggl/algorithms/centroid.hpp>
+#include <ggl/algorithms/num_points.hpp>
+#include <ggl/multi/core/point_type.hpp>
+#include <ggl/multi/algorithms/detail/multi_sum.hpp>
+#include <ggl/multi/algorithms/num_points.hpp>
+
+
+namespace ggl {
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace centroid {
+
+
+/*!
+    \brief Building block of a multi-point, to be used as Policy in the
+        more generec centroid_multi
+*/
+template
+<
+    typename Point,
+    typename Strategy 
+>
+struct centroid_multi_point_state
+{
+    static inline void apply(Point const& point, 
+            Strategy const& strategy, typename Strategy::state_type& state)
+    {
+        strategy.apply(point, state);
+    }
+};
+
+
+
+/*!
+    \brief Generic implementation which calls a policy to calculate the
+        centroid of the total of its single-geometries
+    \details The Policy is, in general, the single-version, with state. So
+        detail::centroid::centroid_polygon_state is used as a policy for this
+        detail::centroid::centroid_multi
+
+*/
+template
+<
+    typename Multi, 
+    typename Point,
+    typename Strategy, 
+    typename Policy
+>
+struct centroid_multi
+{
+    static inline void apply(Multi const& multi, Point& centroid,
+            Strategy const& strategy)
+    {
+        // If there is nothing in any of the ranges, it is not possible 
+        // to calculate the centroid
+        if (ggl::num_points(multi) == 0)
+        {
+            throw centroid_exception();
+        }
+
+        typename Strategy::state_type state;
+
+        for (typename boost::range_const_iterator<Multi>::type 
+                it = boost::begin(multi); 
+            it != boost::end(multi); 
+            ++it)
+        {
+            Policy::apply(*it, strategy, state);
+        }
+        Strategy::result(state, centroid);
+    }
+};
+
+
+
+}} // namespace detail::centroid
+#endif // DOXYGEN_NO_DETAIL
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template 
+<
+    typename MultiPolygon, 
+    typename Point, 
+    typename Strategy
+>
+struct centroid<multi_polygon_tag, MultiPolygon, Point, Strategy>
+    : detail::centroid::centroid_multi
+        <
+            MultiPolygon, 
+            Point,
+            Strategy,
+            detail::centroid::centroid_polygon_state
+                <
+                    typename boost::range_value<MultiPolygon>::type,
+                    Strategy
+                >
+        >
+{};
+
+
+template
+<
+    typename MultiPoint, 
+    typename Point, 
+    typename Strategy
+>
+struct centroid<multi_point_tag, MultiPoint, Point, Strategy>
+    : detail::centroid::centroid_multi
+        <
+            MultiPoint, 
+            Point,
+            Strategy,
+            detail::centroid::centroid_multi_point_state
+                <
+                    typename boost::range_value<MultiPoint>::type,
+                    Strategy
+                >
+        >
+{};
+
+
+} // namespace dispatch
+#endif
+
+
+} // namespace ggl
+
+
+#endif // GGL_MULTI_ALGORITHMS_CENTROID_HPP
+
Added: sandbox/ggl/formal_review/boost/ggl/multi/algorithms/convex_hull.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/multi/algorithms/convex_hull.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,22 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_ALGORITHMS_CONVEX_HULL_HPP
+#define GGL_MULTI_ALGORITHMS_CONVEX_HULL_HPP
+
+
+#include <ggl/multi/iterators/range_type.hpp>
+#include <ggl/multi/util/for_each_range.hpp>
+
+// Note that this file is, furthermore, empty,
+// there is no specialization necessary
+// as this is in fact done by for_each_range
+
+// Might therefore be obsoleted.
+
+
+#endif // GGL_MULTI_ALGORITHMS_CONVEX_HULL_HPP
Added: sandbox/ggl/formal_review/boost/ggl/multi/algorithms/correct.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/multi/algorithms/correct.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,64 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_ALGORITHMS_CORRECT_HPP
+#define GGL_MULTI_ALGORITHMS_CORRECT_HPP
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+
+#include <ggl/algorithms/correct.hpp>
+
+#include <ggl/multi/core/tags.hpp>
+
+
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace correct {
+
+template <typename MultiPolygon>
+struct correct_multi_polygon
+{
+    static inline void apply(MultiPolygon& mp)
+    {
+        typedef typename boost::range_value<MultiPolygon>::type polygon_type;
+        for (typename boost::range_iterator<MultiPolygon>::type it 
+                    = boost::begin(mp); 
+            it != boost::end(mp); 
+            ++it)
+        {
+            correct_polygon<polygon_type>::apply(*it);
+        }
+    }
+};
+
+}} // namespace detail::correct
+#endif
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Geometry>
+struct correct<multi_polygon_tag, Geometry>
+    : detail::correct::correct_multi_polygon<Geometry>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+} // namespace ggl
+
+
+#endif // GGL_MULTI_ALGORITHMS_CORRECT_HPP
Added: sandbox/ggl/formal_review/boost/ggl/multi/algorithms/detail/modify_with_predicate.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/multi/algorithms/detail/modify_with_predicate.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,46 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_ALGORITHMS_DETAIL_MODIFY_WITH_PREDICATE_HPP
+#define GGL_MULTI_ALGORITHMS_DETAIL_MODIFY_WITH_PREDICATE_HPP
+
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+
+namespace ggl {
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail {
+
+template <typename MultiGeometry, typename Predicate, typename Policy>
+struct multi_modify_with_predicate
+{
+    static inline void apply(MultiGeometry& multi, Predicate const& predicate)
+    {
+        typedef typename boost::range_iterator<MultiGeometry>::type iterator_type;
+        for (iterator_type it = boost::begin(multi);
+            it != boost::end(multi);
+            ++it)
+        {
+            Policy::apply(*it, predicate);
+        }
+    }
+};
+
+
+} // namespace detail
+#endif
+
+
+} // namespace ggl
+
+
+#endif // GGL_MULTI_ALGORITHMS_DETAIL_MODIFY_WITH_PREDICATE_HPP
Added: sandbox/ggl/formal_review/boost/ggl/multi/algorithms/detail/multi_sum.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/multi/algorithms/detail/multi_sum.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,53 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_SUM_HPP
+#define GGL_MULTI_SUM_HPP
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+namespace ggl
+{
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+template
+<
+    typename ReturnType,
+    typename MultiGeometry,
+    typename Strategy,
+    typename Policy
+>
+struct multi_sum
+{
+    static inline ReturnType apply(MultiGeometry const& geometry, Strategy const& strategy)
+    {
+        ReturnType sum = ReturnType();
+        for (typename boost::range_const_iterator
+                <
+                    MultiGeometry
+                >::type it = boost::begin(geometry);
+            it != boost::end(geometry);
+            ++it)
+        {
+            sum += Policy::apply(*it, strategy);
+        }
+        return sum;
+    }
+};
+
+
+} // namespace detail
+#endif
+
+} // namespace ggl
+
+
+#endif // GGL_MULTI_SUM_HPP
Added: sandbox/ggl/formal_review/boost/ggl/multi/algorithms/distance.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/multi/algorithms/distance.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,136 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_ALGORITHMS_DISTANCE_HPP
+#define GGL_MULTI_ALGORITHMS_DISTANCE_HPP
+
+
+#include <boost/numeric/conversion/bounds.hpp>
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/multi/core/tags.hpp>
+#include <ggl/multi/core/is_multi.hpp>
+#include <ggl/multi/core/geometry_id.hpp>
+#include <ggl/multi/core/point_type.hpp>
+
+#include <ggl/algorithms/distance.hpp>
+#include <ggl/util/select_coordinate_type.hpp>
+
+
+namespace ggl {
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace distance {
+
+
+template<typename Geometry, typename MultiGeometry, typename Strategy>
+struct distance_single_to_multi
+{
+    typedef typename Strategy::return_type return_type;
+    static inline return_type apply(Geometry const& geometry,
+                MultiGeometry const& multi,
+                Strategy const& strategy)
+    {
+        using namespace boost;
+
+        return_type mindist = make_distance_result<return_type>(
+                numeric::bounds
+                    <
+                        typename select_coordinate_type
+                            <
+                                Geometry,
+                                MultiGeometry
+                            >::type
+                    >::highest());
+
+        for(typename range_const_iterator<MultiGeometry>::type it = begin(multi);
+                it != end(multi);
+                ++it)
+        {
+            return_type dist = ggl::distance(geometry, *it);
+            if (dist < mindist)
+            {
+                mindist = dist;
+            }
+        }
+
+        return mindist;
+    }
+};
+
+template<typename Multi1, typename Multi2, typename Strategy>
+struct distance_multi_to_multi
+{
+    typedef typename Strategy::return_type return_type;
+
+    static inline return_type apply(Multi1 const& multi1,
+                Multi2 const& multi2, Strategy const& strategy)
+    {
+        using namespace boost;
+
+        return_type mindist = make_distance_result<return_type>(
+                numeric::bounds
+                    <
+                        typename select_coordinate_type
+                            <
+                                Multi1,
+                                Multi2
+                            >::type
+                    >::highest());
+
+        for(typename range_const_iterator<Multi1>::type it = begin(multi1);
+                it != end(multi1);
+                ++it)
+        {
+            return_type dist = distance_single_to_multi
+                <
+                    typename range_value<Multi1>::type,
+                    Multi2,
+                    Strategy
+                >::apply(*it, multi2, strategy);
+            if (dist < mindist)
+            {
+                mindist = dist;
+            }
+        }
+
+        return mindist;
+    }
+};
+
+
+}} // namespace detail::distance
+#endif
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename GeometryTag1, typename GeometryTag2,
+        typename G1, typename G2, typename Strategy>
+struct distance<GeometryTag1, GeometryTag2, G1, G2, strategy_tag_distance_point_point, Strategy, false, true>
+    : detail::distance::distance_single_to_multi<G1, G2, Strategy>
+{};
+
+template <typename GeometryTag1, typename GeometryTag2,
+        typename G1, typename G2, typename Strategy>
+struct distance<GeometryTag1, GeometryTag2, G1, G2, strategy_tag_distance_point_point, Strategy, true, true>
+    : detail::distance::distance_multi_to_multi<G1, G2, Strategy>
+{};
+
+} // namespace dispatch
+#endif
+
+
+
+} // namespace ggl
+
+
+#endif // GGL_MULTI_ALGORITHMS_DISTANCE_HPP
Added: sandbox/ggl/formal_review/boost/ggl/multi/algorithms/envelope.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/multi/algorithms/envelope.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,110 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_ALGORITHMS_ENVELOPE_HPP
+#define GGL_MULTI_ALGORITHMS_ENVELOPE_HPP
+
+#include <vector>
+
+#include <ggl/core/exterior_ring.hpp>
+#include <ggl/algorithms/envelope.hpp>
+
+#include <ggl/multi/core/point_type.hpp>
+
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+
+namespace detail { namespace envelope {
+
+
+template<typename MultiLinestring, typename Box>
+struct envelope_multi_linestring
+{
+    static inline void apply(MultiLinestring const& mp, Box& mbr)
+    {
+        assign_inverse(mbr);
+        for (typename boost::range_const_iterator<MultiLinestring>::type
+                    it = mp.begin();
+            it != mp.end();
+            ++it)
+        {
+            envelope_range_additional(*it, mbr);
+        }
+    }
+};
+
+
+// version for multi_polygon: outer linear_ring's of all polygons
+template<typename MultiPolygon, typename Box>
+struct envelope_multi_polygon
+{
+    static inline void apply(MultiPolygon const& mp, Box& mbr)
+    {
+        assign_inverse(mbr);
+        for (typename boost::range_const_iterator<MultiPolygon>::type
+                    it = mp.begin();
+            it != mp.end();
+            ++it)
+        {
+            envelope_range_additional(exterior_ring(*it), mbr);
+        }
+    }
+};
+
+
+}} // namespace detail::envelope
+
+#endif
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template 
+<
+    typename Multi, typename Box, 
+    typename StrategyLess, typename StrategyGreater
+>
+struct envelope<multi_point_tag, box_tag, Multi, Box, StrategyLess, StrategyGreater>
+    : detail::envelope::envelope_range<Multi, Box>
+{};
+
+template 
+<
+    typename Multi, typename Box, 
+    typename StrategyLess, typename StrategyGreater
+>
+struct envelope<multi_linestring_tag, box_tag, Multi, Box, StrategyLess, StrategyGreater>
+    : detail::envelope::envelope_multi_linestring<Multi, Box>
+{};
+
+
+template 
+<
+    typename Multi, typename Box, 
+    typename StrategyLess, typename StrategyGreater
+>
+struct envelope<multi_polygon_tag, box_tag, Multi, Box, StrategyLess, StrategyGreater>
+    : detail::envelope::envelope_multi_polygon<Multi, Box>
+{};
+
+
+} // namespace dispatch
+#endif
+
+
+
+
+} // namespace ggl
+
+
+#endif // GGL_MULTI_ALGORITHMS_ENVELOPE_HPP
Added: sandbox/ggl/formal_review/boost/ggl/multi/algorithms/for_each.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/multi/algorithms/for_each.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,126 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_ALGORITHMS_FOR_EACH_HPP
+#define GGL_MULTI_ALGORITHMS_FOR_EACH_HPP
+
+
+#include <ggl/multi/core/tags.hpp>
+#include <ggl/multi/core/is_multi.hpp>
+#include <ggl/multi/core/point_type.hpp>
+
+
+#include <ggl/algorithms/for_each.hpp>
+
+
+
+namespace ggl
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace for_each {
+
+// Implementation of multi, for both point and segment,
+// just calling the single version.
+template
+<
+    typename MultiGeometry,
+    typename Functor,
+    bool IsConst,
+    typename Policy
+>
+struct for_each_multi
+{
+    static inline Functor apply(
+                    typename add_const_if_c<IsConst, MultiGeometry>::type& multi,
+                    Functor f)
+    {
+        typedef typename range_iterator_const_if_c
+            <
+                IsConst,
+                MultiGeometry
+            >::type iterator_type;
+
+        for(iterator_type it = boost::begin(multi);
+            it != boost::end(multi);
+            ++it)
+        {
+            f = Policy::apply(*it, f);
+        }
+        return f;
+    }
+};
+
+
+}} // namespace detail::for_each
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template 
+<
+    typename MultiTag, 
+    typename MultiGeometry, 
+    typename Functor, 
+    bool IsConst
+>
+struct for_each_point<MultiTag, true, MultiGeometry, Functor, IsConst>
+    : detail::for_each::for_each_multi
+        <
+            MultiGeometry, 
+            Functor, 
+            IsConst,
+            // Specify the dispatch of the single-version as policy
+            for_each_point
+                <
+                    typename single_tag<MultiTag>::type,
+                    false,
+                    typename boost::range_value<MultiGeometry>::type,
+                    Functor,
+                    IsConst
+                >
+        >
+{};
+
+
+template 
+<
+    typename MultiTag, 
+    typename MultiGeometry, 
+    typename Functor, 
+    bool IsConst
+>
+struct for_each_segment<MultiTag, true, MultiGeometry, Functor, IsConst>
+    : detail::for_each::for_each_multi
+        <
+            MultiGeometry, 
+            Functor, 
+            IsConst,
+            // Specify the dispatch of the single-version as policy
+            for_each_segment
+                <
+                    typename single_tag<MultiTag>::type,
+                    false,
+                    typename boost::range_value<MultiGeometry>::type,
+                    Functor,
+                    IsConst
+                >
+        >
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+} // namespace ggl
+
+
+#endif // GGL_MULTI_ALGORITHMS_FOR_EACH_HPP
Added: sandbox/ggl/formal_review/boost/ggl/multi/algorithms/get_section.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/multi/algorithms/get_section.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,60 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_ALGORITHMS_GET_SECTION_HPP
+#define GGL_MULTI_ALGORITHMS_GET_SECTION_HPP
+
+
+#include <boost/concept/requires.hpp>
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/multi/core/tags.hpp>
+
+#include <ggl/algorithms/get_section.hpp>
+
+
+
+namespace ggl
+{
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename MultiPolygon, typename Section>
+struct get_section<multi_polygon_tag, MultiPolygon, Section>
+{
+    typedef typename boost::range_const_iterator
+        <
+            typename ggl::range_type<MultiPolygon>::type
+        >::type iterator_type;
+
+    static inline void apply(MultiPolygon const& multi_polygon, Section const& section,
+                iterator_type& begin, iterator_type& end)
+    {
+        BOOST_ASSERT(section.multi_index >= 0 && section.multi_index < boost::size(multi_polygon));
+
+        get_section<polygon_tag, typename boost::range_value<MultiPolygon>::type, Section>
+            ::apply(multi_polygon[section.multi_index], section, begin, end);
+
+    }
+};
+
+
+} // namespace dispatch
+#endif
+
+
+
+
+} // namespace ggl
+
+#endif // GGL_MULTI_ALGORITHMS_GET_SECTION_HPP
Added: sandbox/ggl/formal_review/boost/ggl/multi/algorithms/intersection.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/multi/algorithms/intersection.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,47 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_ALGORITHMS_INTERSECTION_HPP
+#define GGL_MULTI_ALGORITHMS_INTERSECTION_HPP
+
+#include <vector>
+
+#include <ggl/algorithms/intersection.hpp>
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template
+<
+    typename MultiPolygon1, typename MultiPolygon2,
+    typename OutputIterator, typename GeometryOut
+>
+struct intersection_inserter
+    <
+        multi_polygon_tag, multi_polygon_tag, polygon_tag,
+        MultiPolygon1, MultiPolygon2,
+        OutputIterator, GeometryOut
+    >
+{
+    // todo: implement this
+};
+
+
+} // namespace dispatch
+#endif
+
+} // namespace ggl
+
+
+#endif // GGL_MULTI_ALGORITHMS_INTERSECTION_HPP
+
Added: sandbox/ggl/formal_review/boost/ggl/multi/algorithms/length.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/multi/algorithms/length.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,45 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_ALGORITHMS_LENGTH_HPP
+#define GGL_MULTI_ALGORITHMS_LENGTH_HPP
+
+#include <ggl/algorithms/length.hpp>
+#include <ggl/multi/core/tags.hpp>
+#include <ggl/multi/algorithms/detail/multi_sum.hpp>
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename MultiLinestring, typename Strategy>
+struct length<multi_linestring_tag, MultiLinestring, Strategy>
+    : detail::multi_sum
+        <
+            typename length_result<MultiLinestring>::type,
+            MultiLinestring,
+            Strategy,
+            detail::length::range_length
+                <
+                    typename boost::range_value<MultiLinestring>::type,
+                    Strategy
+                >
+        >
+{};
+
+
+} // namespace dispatch
+#endif
+
+
+} // namespace ggl
+
+
+#endif // GGL_MULTI_ALGORITHMS_LENGTH_HPP
Added: sandbox/ggl/formal_review/boost/ggl/multi/algorithms/num_points.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/multi/algorithms/num_points.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,78 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_MULTI_ALGORITHMS_NUM_POINTS_HPP
+#define GGL_MULTI_ALGORITHMS_NUM_POINTS_HPP
+
+
+#include <ggl/multi/core/tags.hpp>
+#include <ggl/algorithms/num_points.hpp>
+
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace num_points {
+
+
+template <typename MultiGeometry>
+struct multi_count
+{
+    static inline size_t apply(MultiGeometry const& geometry)
+    {
+        typedef typename boost::range_value<MultiGeometry>::type geometry_type;
+        typedef typename boost::remove_const<geometry_type>::type ncg;
+        typedef typename boost::range_const_iterator
+            <
+                MultiGeometry
+            >::type iterator_type;
+
+        size_t n = 0;
+        for (iterator_type it = boost::begin(geometry);
+            it != boost::end(geometry);
+            ++it)
+        {
+            n += dispatch::num_points<typename tag<ncg>::type,
+                ggl::is_linear<ncg>::value, ncg>::apply(*it);
+        }
+        return n;
+    }
+};
+
+
+}} // namespace detail::num_points
+#endif
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch {
+
+
+template <typename Geometry>
+struct num_points<multi_point_tag, false, Geometry>
+    : detail::num_points::multi_count<Geometry> {};
+
+template <typename Geometry>
+struct num_points<multi_linestring_tag, false, Geometry>
+    : detail::num_points::multi_count<Geometry> {};
+
+template <typename Geometry>
+struct num_points<multi_polygon_tag, false, Geometry>
+    : detail::num_points::multi_count<Geometry> {};
+
+
+} // namespace dispatch
+#endif
+
+
+}
+
+
+#endif // GGL_MULTI_ALGORITHMS_NUM_POINTS_HPP
Added: sandbox/ggl/formal_review/boost/ggl/multi/algorithms/overlay/copy_segments.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/multi/algorithms/overlay/copy_segments.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,92 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_ALGORITHMS_OVERLAY_COPY_SEGMENTS_HPP
+#define GGL_MULTI_ALGORITHMS_OVERLAY_COPY_SEGMENTS_HPP
+
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/algorithms/overlay/copy_segments.hpp>
+
+#include <ggl/multi/core/ring_type.hpp>
+#include <ggl/multi/core/tags.hpp>
+
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace copy_segments {
+
+
+template
+<
+    typename MultiGeometry,
+    typename SegmentIdentifier,
+    typename RangeOut,
+    typename Policy
+>
+struct copy_segments_multi
+{
+    static inline void apply(MultiGeometry const& multi_geometry,
+            SegmentIdentifier const& seg_id, int to_index,
+            RangeOut& current_output)
+    {
+
+        BOOST_ASSERT
+            (
+                seg_id.multi_index >= 0
+                && seg_id.multi_index < boost::size(multi_geometry)
+            );
+
+        // Call the single-version
+        Policy::apply(multi_geometry[seg_id.multi_index],
+                    seg_id, to_index, current_output);
+    }
+};
+
+
+}} // namespace detail::copy_segments
+#endif // DOXYGEN_NO_DETAIL
+
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch {
+
+
+
+template <typename MultiPolygon, typename SegmentIdentifier, typename RangeOut>
+struct copy_segments<multi_polygon_tag, MultiPolygon, SegmentIdentifier, RangeOut>
+    : detail::copy_segments::copy_segments_multi
+        <
+            MultiPolygon,
+            SegmentIdentifier,
+            RangeOut,
+            detail::copy_segments::copy_segments_polygon
+                <
+                    typename boost::range_value<MultiPolygon>::type,
+                    SegmentIdentifier,
+                    RangeOut
+                >
+        >
+{};
+
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+
+} // namespace ggl
+
+#endif // GGL_MULTI_ALGORITHMS_OVERLAY_COPY_SEGMENTS_HPP
Added: sandbox/ggl/formal_review/boost/ggl/multi/algorithms/overlay/get_intersection_points.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/multi/algorithms/overlay/get_intersection_points.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,64 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_ALGORITHMS_GET_INTERSECTION_POINTS_HPP
+#define GGL_MULTI_ALGORITHMS_GET_INTERSECTION_POINTS_HPP
+
+#include <ggl/multi/core/is_multi.hpp>
+
+#include <ggl/multi/algorithms/distance.hpp>
+#include <ggl/multi/algorithms/get_section.hpp>
+#include <ggl/multi/algorithms/sectionalize.hpp>
+
+#include <ggl/multi/iterators/range_type.hpp>
+
+#include <ggl/algorithms/overlay/get_intersection_points.hpp>
+
+
+
+namespace ggl
+{
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template
+<
+    typename MultiTag1,
+    typename MultiTag2,
+    typename MultiGeometry1,
+    typename MultiGeometry2,
+    typename IntersectionPoints
+>
+struct get_intersection_points
+    <
+        MultiTag1, MultiTag2,
+        true, true,
+        MultiGeometry1, MultiGeometry2,
+        IntersectionPoints
+    >
+    : detail::get_intersection_points::get_ips_generic
+        <
+            MultiGeometry1,
+            MultiGeometry2,
+            IntersectionPoints
+        >
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+
+} // namespace ggl
+
+#endif // GGL_MULTI_ALGORITHMS_GET_INTERSECTION_POINTS_HPP
Added: sandbox/ggl/formal_review/boost/ggl/multi/algorithms/perimeter.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/multi/algorithms/perimeter.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,47 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_ALGORITHMS_PERIMETER_HPP
+#define GGL_MULTI_ALGORITHMS_PERIMETER_HPP
+
+#include <ggl/algorithms/perimeter.hpp>
+
+#include <ggl/multi/core/tags.hpp>
+
+#include <ggl/multi/algorithms/detail/multi_sum.hpp>
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+template <typename MultiPolygon, typename Strategy>
+struct perimeter<multi_polygon_tag, MultiPolygon, Strategy>
+    : detail::multi_sum
+        <
+            typename length_result<MultiPolygon>::type,
+            MultiPolygon,
+            Strategy,
+            perimeter
+                <
+                    polygon_tag,
+                    typename boost::range_value<MultiPolygon>::type,
+                    Strategy
+                >
+        >
+{};
+
+} // namespace dispatch
+#endif
+
+
+} // namespace ggl
+
+
+#endif // GGL_MULTI_ALGORITHMS_PERIMETER_HPP
Added: sandbox/ggl/formal_review/boost/ggl/multi/algorithms/sectionalize.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/multi/algorithms/sectionalize.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,86 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_ALGORITHMS_SECTIONALIZE_HPP
+#define GGL_MULTI_ALGORITHMS_SECTIONALIZE_HPP
+
+#include <cstddef>
+#include <vector>
+
+#include <boost/concept/requires.hpp>
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/algorithms/sectionalize.hpp>
+
+
+
+namespace ggl
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace sectionalize {
+
+
+template <typename MultiGeometry, typename Sections, std::size_t DimensionCount, typename Policy>
+struct sectionalize_multi
+{
+    static inline void apply(MultiGeometry const& multi, Sections& sections)
+    {
+        int multi_index = 0;
+        for (typename boost::range_const_iterator<MultiGeometry>::type
+                    it = boost::begin(multi);
+            it != boost::end(multi);
+            ++it, ++multi_index)
+        {
+            Policy::apply(*it, sections, multi_index);
+        }
+    }
+};
+
+
+
+
+}} // namespace detail::sectionalize
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename MultiPolygon, typename Sections, std::size_t DimensionCount, std::size_t MaxCount>
+struct sectionalize<multi_polygon_tag, MultiPolygon, Sections, DimensionCount, MaxCount>
+    : detail::sectionalize::sectionalize_multi
+        <
+            MultiPolygon,
+            Sections,
+            DimensionCount,
+            detail::sectionalize::sectionalize_polygon
+                <
+                    typename boost::range_value<MultiPolygon>::type,
+                    Sections,
+                    DimensionCount,
+                    MaxCount
+                >
+        >
+
+{};
+
+
+} // namespace dispatch
+#endif
+
+
+
+
+} // namespace ggl
+
+#endif // GGL_MULTI_ALGORITHMS_SECTIONALIZE_HPP
Added: sandbox/ggl/formal_review/boost/ggl/multi/algorithms/simplify.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/multi/algorithms/simplify.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,112 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_ALGORITHMS_SIMPLIFY_HPP
+#define GGL_MULTI_ALGORITHMS_SIMPLIFY_HPP
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/multi/core/tags.hpp>
+#include <ggl/multi/core/is_multi.hpp>
+
+#include <ggl/multi/iterators/range_type.hpp>
+
+#include <ggl/algorithms/simplify.hpp>
+
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace simplify {
+
+template<typename MultiGeometry, typename Strategy, typename Policy>
+struct simplify_multi
+{
+    static inline void apply(MultiGeometry const& multi, MultiGeometry& out,
+                    double max_distance, Strategy const& strategy)
+    {
+        out.resize(boost::size(multi));
+
+        typename boost::range_iterator<MultiGeometry>::type it_out 
+                = boost::begin(out);
+        for (typename boost::range_const_iterator<MultiGeometry>::type it_in 
+                    = boost::begin(multi); 
+            it_in != boost::end(multi); 
+            ++it_in, ++it_out)
+        {
+            Policy::apply(*it_in, *it_out, max_distance, strategy);
+        }
+    }
+};
+
+
+
+}} // namespace detail::simplify
+#endif // DOXYGEN_NO_DETAIL
+
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename MultiPoint, typename Strategy>
+struct simplify<multi_point_tag, MultiPoint, Strategy>
+    : detail::simplify::simplify_copy
+        <
+            MultiPoint,
+            Strategy
+        >
+
+{};
+
+
+template <typename MultiLinestring, typename Strategy>
+struct simplify<multi_linestring_tag, MultiLinestring, Strategy>
+    : detail::simplify::simplify_multi
+        <
+            MultiLinestring,
+            Strategy,
+            detail::simplify::simplify_range
+                <
+                    typename boost::range_value<MultiLinestring>::type,
+                    Strategy,
+                    2
+                >
+        >
+
+{};
+
+
+template <typename MultiPolygon, typename Strategy>
+struct simplify<multi_polygon_tag, MultiPolygon, Strategy>
+    : detail::simplify::simplify_multi
+        <
+            MultiPolygon,
+            Strategy,
+            detail::simplify::simplify_polygon
+                <
+                    typename boost::range_value<MultiPolygon>::type,
+                    Strategy
+                >
+        >
+
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+} // namespace ggl
+
+
+#endif // GGL_MULTI_ALGORITHMS_SIMPLIFY_HPP
Added: sandbox/ggl/formal_review/boost/ggl/multi/algorithms/transform.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/multi/algorithms/transform.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,93 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_ALGORITHMS_TRANSFORM_HPP
+#define GGL_MULTI_ALGORITHMS_TRANSFORM_HPP
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/algorithms/transform.hpp>
+
+#include <ggl/multi/core/tags.hpp>
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace transform {
+
+/*!
+    \brief Is able to transform any multi-geometry, calling the single-version as policy
+*/
+template <typename Multi1, typename Multi2, typename Policy>
+struct transform_multi
+{
+    template <typename S>
+    static inline bool apply(Multi1 const& multi1, Multi2& multi2, S const& strategy)
+    {
+        multi2.resize(boost::size(multi1));
+
+        typename boost::range_const_iterator<Multi1>::type it1 
+                = boost::begin(multi1);
+        typename boost::range_iterator<Multi2>::type it2 
+                = boost::begin(multi2);
+
+        for (; it1 != boost::end(multi1); ++it1, ++it2)
+        {
+            if (! Policy::apply(*it1, *it2, strategy))
+            {
+                return false;
+            }
+        }
+
+        return true;
+    }
+};
+
+
+
+
+}} // namespace detail::transform
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename Multi1, typename Multi2, typename Strategy>
+struct transform
+    <
+        multi_polygon_tag, multi_polygon_tag, 
+        Multi1, Multi2, 
+        Strategy
+    >
+    : detail::transform::transform_multi
+        <
+            Multi1,
+            Multi2,
+            detail::transform::transform_polygon
+                <
+                    typename boost::range_value<Multi1>::type,
+                    typename boost::range_value<Multi2>::type,
+                    Strategy
+                >
+        >
+{};
+
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+} // namespace ggl
+
+#endif // GGL_MULTI_ALGORITHMS_TRANSFORM_HPP
Added: sandbox/ggl/formal_review/boost/ggl/multi/algorithms/within.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/multi/algorithms/within.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,82 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_ALGORITHMS_WITHIN_HPP
+#define GGL_MULTI_ALGORITHMS_WITHIN_HPP
+
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/algorithms/within.hpp>
+#include <ggl/multi/core/tags.hpp>
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace within {
+
+
+template
+<
+    typename Geometry, 
+    typename MultiGeometry, 
+    typename Strategy, 
+    typename Policy
+>
+struct geometry_in_multi
+{
+    static inline bool apply(Geometry const& geometry, 
+            MultiGeometry const& multi, 
+            Strategy const& strategy)
+    {
+        for (typename boost::range_const_iterator<MultiGeometry>::type it
+                    = boost::begin(multi); 
+            it != boost::end(multi); 
+            ++it)
+        {
+            // Geometry within a multi: true if within one of them
+            if (Policy::apply(geometry, *it, strategy))
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+};
+
+}} // namespace detail::within
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Point, typename MultiPolygon, typename Strategy>
+struct within<point_tag, multi_polygon_tag, Point, MultiPolygon, Strategy>
+    : detail::within::geometry_in_multi
+        <
+            Point, 
+            MultiPolygon, 
+            Strategy,
+            detail::within::point_in_polygon
+                    <
+                        Point, 
+                        typename boost::range_value<MultiPolygon>::type,
+                        Strategy
+                    >
+        >
+{};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+} // namespace ggl
+
+#endif // GGL_MULTI_ALGORITHMS_WITHIN_HPP
Added: sandbox/ggl/formal_review/boost/ggl/multi/core/geometry_id.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/multi/core/geometry_id.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,51 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_MULTI_CORE_GEOMETRY_ID_HPP
+#define GGL_MULTI_CORE_GEOMETRY_ID_HPP
+
+
+#include <boost/mpl/int.hpp>
+#include <boost/type_traits.hpp>
+
+
+#include <ggl/core/tag.hpp>
+#include <ggl/core/tags.hpp>
+#include <ggl/core/geometry_id.hpp>
+#include <ggl/multi/core/tags.hpp>
+
+
+namespace ggl {
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+template <>
+struct geometry_id<multi_point_tag>      : boost::mpl::int_<4> {};
+
+
+template <>
+struct geometry_id<multi_linestring_tag> : boost::mpl::int_<5> {};
+
+
+template <>
+struct geometry_id<multi_polygon_tag>    : boost::mpl::int_<6> {};
+
+
+
+} // namespace core_dispatch
+#endif
+
+
+} // namespace ggl
+
+
+#endif // GGL_MULTI_CORE_GEOMETRY_ID_HPP
Added: sandbox/ggl/formal_review/boost/ggl/multi/core/is_multi.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/multi/core/is_multi.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,49 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_MULTI_CORE_IS_MULTI_HPP
+#define GGL_MULTI_CORE_IS_MULTI_HPP
+
+
+#include <boost/type_traits.hpp>
+
+
+#include <ggl/core/is_multi.hpp>
+#include <ggl/multi/core/tags.hpp>
+
+
+namespace ggl {
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+template <>
+struct is_multi<multi_point_tag> : boost::true_type {};
+
+
+template <>
+struct is_multi<multi_linestring_tag> : boost::true_type {};
+
+
+template <>
+struct is_multi<multi_polygon_tag> : boost::true_type {};
+
+
+} // namespace core_dispatch
+#endif
+
+
+
+
+} // namespace ggl
+
+
+#endif // GGL_MULTI_CORE_IS_MULTI_HPP
Added: sandbox/ggl/formal_review/boost/ggl/multi/core/point_type.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/multi/core/point_type.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,59 @@
+// Generic Geometry Library
+//
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_MULTI_CORE_POINT_TYPE_HPP
+#define GGL_MULTI_CORE_POINT_TYPE_HPP
+
+
+#include <boost/range/metafunctions.hpp>
+
+
+#include <ggl/core/point_type.hpp>
+#include <ggl/multi/core/tags.hpp>
+
+
+
+namespace ggl {
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+template <typename MultiPoint>
+struct point_type<multi_point_tag, MultiPoint>
+{
+    typedef typename boost::range_value<MultiPoint>::type type;
+};
+
+
+template <typename MultiLinestring>
+struct point_type<multi_linestring_tag, MultiLinestring>
+{
+    typedef typename point_type<linestring_tag,
+        typename boost::range_value<MultiLinestring>::type>::type type;
+};
+
+
+
+template <typename MultiPolygon>
+struct point_type<multi_polygon_tag, MultiPolygon>
+{
+    typedef typename point_type<polygon_tag,
+        typename boost::range_value<MultiPolygon>::type>::type type;
+};
+
+
+
+
+}
+#endif
+
+} // namespace ggl
+
+#endif // GGL_MULTI_CORE_POINT_TYPE_HPP
Added: sandbox/ggl/formal_review/boost/ggl/multi/core/ring_type.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/multi/core/ring_type.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,48 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_MULTI_CORE_RING_TYPE_HPP
+#define GGL_MULTI_CORE_RING_TYPE_HPP
+
+
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/core/ring_type.hpp>
+#include <ggl/multi/core/tags.hpp>
+
+
+
+namespace ggl
+{
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+template <typename MultiPolygon>
+struct ring_type<multi_polygon_tag, MultiPolygon>
+{
+    typedef typename ggl::ring_type
+        <
+            typename boost::range_value<MultiPolygon>::type
+        >::type type;
+};
+
+
+
+
+} // namespace core_dispatch
+#endif
+
+
+} // namespace ggl
+
+
+#endif // GGL_MULTI_CORE_RING_TYPE_HPP
Added: sandbox/ggl/formal_review/boost/ggl/multi/core/tags.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/multi/core/tags.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,66 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_MULTI_CORE_TAGS_HPP
+#define GGL_MULTI_CORE_TAGS_HPP
+
+#include <ggl/core/tags.hpp>
+
+namespace ggl
+{
+
+/// OGC Multi point identifying tag
+struct multi_point_tag {};
+
+/// OGC Multi linestring identifying tag
+struct multi_linestring_tag {};
+
+/// OGC Multi polygon identifying tag
+struct multi_polygon_tag {};
+
+/// OGC Geometry Collection identifying tag
+struct geometry_collection_tag {};
+
+
+
+
+/*!
+    \brief Meta-function to get for a tag of a multi-geometry
+        the tag of the corresponding single-geometry
+*/
+template <typename Tag>
+struct single_tag
+{};
+
+#ifndef DOXYGEN_NO_DETAIL
+
+template <>
+struct single_tag<multi_point_tag>
+{
+    typedef point_tag type;
+};
+
+template <>
+struct single_tag<multi_linestring_tag>
+{
+    typedef linestring_tag type;
+};
+
+template <>
+struct single_tag<multi_polygon_tag>
+{
+    typedef polygon_tag type;
+};
+
+#endif
+
+
+} // namespace ggl
+
+#endif // GGL_MULTI_CORE_TAGS_HPP
Added: sandbox/ggl/formal_review/boost/ggl/multi/core/topological_dimension.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/multi/core/topological_dimension.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,45 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_MULTI_TOPOLOGICAL_DIMENSION_HPP
+#define GGL_MULTI_TOPOLOGICAL_DIMENSION_HPP
+
+
+#include <boost/mpl/int.hpp>
+
+
+#include <ggl/core/topological_dimension.hpp>
+#include <ggl/multi/core/tags.hpp>
+
+
+namespace ggl {
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace core_dispatch
+{
+
+template <>
+struct top_dim<multi_point_tag> : boost::mpl::int_<0> {};
+
+
+template <>
+struct top_dim<multi_linestring_tag> : boost::mpl::int_<1> {};
+
+
+template <>
+struct top_dim<multi_polygon_tag> : boost::mpl::int_<2> {};
+
+
+} // namespace core_dispatch
+#endif
+
+} // namespace ggl
+
+
+#endif
Added: sandbox/ggl/formal_review/boost/ggl/multi/geometries/concepts/check.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/multi/geometries/concepts/check.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,76 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 2009, Geodan, Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_MULTI_GEOMETRIES_CONCEPTS_CHECK_HPP
+#define GGL_MULTI_GEOMETRIES_CONCEPTS_CHECK_HPP
+
+
+
+#include <boost/type_traits/is_const.hpp>
+
+#include <ggl/multi/core/tags.hpp>
+
+#include <ggl/geometries/concepts/check.hpp>
+#include <ggl/multi/geometries/concepts/multi_point_concept.hpp>
+#include <ggl/multi/geometries/concepts/multi_linestring_concept.hpp>
+#include <ggl/multi/geometries/concepts/multi_polygon_concept.hpp>
+
+
+namespace ggl {
+
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename Geometry>
+struct check<multi_point_tag, Geometry, true>
+    : detail::concept_check::check<concept::ConstMultiPoint<Geometry> >
+{};
+
+
+template <typename Geometry>
+struct check<multi_point_tag, Geometry, false>
+    : detail::concept_check::check<concept::MultiPoint<Geometry> >
+{};
+
+
+template <typename Geometry>
+struct check<multi_linestring_tag, Geometry, true>
+    : detail::concept_check::check<concept::ConstMultiLinestring<Geometry> >
+{};
+
+
+template <typename Geometry>
+struct check<multi_linestring_tag, Geometry, false>
+    : detail::concept_check::check<concept::MultiLinestring<Geometry> >
+{};
+
+
+template <typename Geometry>
+struct check<multi_polygon_tag, Geometry, true>
+    : detail::concept_check::check<concept::ConstMultiPolygon<Geometry> >
+{};
+
+
+template <typename Geometry>
+struct check<multi_polygon_tag, Geometry, false>
+    : detail::concept_check::check<concept::MultiPolygon<Geometry> >
+{};
+
+
+} // namespace dispatch
+#endif
+
+
+} // namespace ggl
+
+
+#endif // GGL_MULTI_GEOMETRIES_CONCEPTS_CHECK_HPP
Added: sandbox/ggl/formal_review/boost/ggl/multi/geometries/concepts/multi_linestring_concept.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/multi/geometries/concepts/multi_linestring_concept.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,80 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_MULTI_GEOMETRIES_CONCEPTS_MULTI_LINESTRING_CONCEPT_HPP
+#define GGL_MULTI_GEOMETRIES_CONCEPTS_MULTI_LINESTRING_CONCEPT_HPP
+
+
+#include <boost/concept_check.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/metafunctions.hpp>
+
+
+#include <ggl/geometries/concepts/linestring_concept.hpp>
+
+
+namespace ggl { namespace concept {
+
+
+/*!
+\brief multi-linestring concept
+\ingroup concepts
+\par Formal definition:
+The multi linestring concept is defined as following:
+- there must be a specialization of traits::tag defining multi_linestring_tag as
+  type
+- it must behave like a Boost.Range
+- its range value must fulfil the Linestring concept
+
+*/
+template <typename Geometry>
+class MultiLinestring
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+    typedef typename boost::range_value<Geometry>::type linestring_type;
+
+    BOOST_CONCEPT_ASSERT( (concept::Linestring<linestring_type>) );
+    BOOST_CONCEPT_ASSERT( (boost::RandomAccessRangeConcept<Geometry>) );
+
+
+public :
+
+    BOOST_CONCEPT_USAGE(MultiLinestring)
+    {
+    }
+#endif
+};
+
+
+/*!
+\brief concept for multi-linestring (const version)
+\ingroup const_concepts
+*/
+template <typename Geometry>
+class ConstMultiLinestring
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+    typedef typename boost::range_value<Geometry>::type linestring_type;
+
+    BOOST_CONCEPT_ASSERT( (concept::ConstLinestring<linestring_type>) );
+    BOOST_CONCEPT_ASSERT( (boost::RandomAccessRangeConcept<Geometry>) );
+
+
+public :
+
+    BOOST_CONCEPT_USAGE(ConstMultiLinestring)
+    {
+    }
+#endif
+};
+
+}} // namespace ggl::concept
+
+
+#endif // GGL_MULTI_GEOMETRIES_CONCEPTS_MULTI_LINESTRING_CONCEPT_HPP
Added: sandbox/ggl/formal_review/boost/ggl/multi/geometries/concepts/multi_point_concept.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/multi/geometries/concepts/multi_point_concept.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,79 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_MULTI_GEOMETRIES_CONCEPTS_MULTI_POINT_CONCEPT_HPP
+#define GGL_MULTI_GEOMETRIES_CONCEPTS_MULTI_POINT_CONCEPT_HPP
+
+
+#include <boost/concept_check.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/metafunctions.hpp>
+
+
+#include <ggl/geometries/concepts/point_concept.hpp>
+
+
+namespace ggl { namespace concept {
+
+
+/*!
+\brief MultiPoint concept
+\ingroup concepts
+\par Formal definition:
+The multi point concept is defined as following:
+- there must be a specialization of traits::tag defining multi_point_tag as type
+- it must behave like a Boost.Range
+- its range value must fulfil the Point concept
+
+*/
+template <typename Geometry>
+class MultiPoint
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+    typedef typename boost::range_value<Geometry>::type point_type;
+
+    BOOST_CONCEPT_ASSERT( (concept::Point<point_type>) );
+    BOOST_CONCEPT_ASSERT( (boost::RandomAccessRangeConcept<Geometry>) );
+
+
+public :
+
+    BOOST_CONCEPT_USAGE(MultiPoint)
+    {
+    }
+#endif
+};
+
+
+/*!
+\brief concept for multi-point (const version)
+\ingroup const_concepts
+*/
+template <typename Geometry>
+class ConstMultiPoint
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+    typedef typename boost::range_value<Geometry>::type point_type;
+
+    BOOST_CONCEPT_ASSERT( (concept::ConstPoint<point_type>) );
+    BOOST_CONCEPT_ASSERT( (boost::RandomAccessRangeConcept<Geometry>) );
+
+
+public :
+
+    BOOST_CONCEPT_USAGE(ConstMultiPoint)
+    {
+    }
+#endif
+};
+
+}} // namespace ggl::concept
+
+
+#endif // GGL_MULTI_GEOMETRIES_CONCEPTS_MULTI_POINT_CONCEPT_HPP
Added: sandbox/ggl/formal_review/boost/ggl/multi/geometries/concepts/multi_polygon_concept.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/multi/geometries/concepts/multi_polygon_concept.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,80 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_MULTI_GEOMETRIES_CONCEPTS_MULTI_POLYGON_CONCEPT_HPP
+#define GGL_MULTI_GEOMETRIES_CONCEPTS_MULTI_POLYGON_CONCEPT_HPP
+
+
+#include <boost/concept_check.hpp>
+#include <boost/range/concepts.hpp>
+#include <boost/range/metafunctions.hpp>
+
+
+#include <ggl/geometries/concepts/polygon_concept.hpp>
+
+
+namespace ggl { namespace concept {
+
+
+/*!
+\brief multi-polygon concept
+\ingroup concepts
+\par Formal definition:
+The multi polygon concept is defined as following:
+- there must be a specialization of traits::tag defining multi_polygon_tag
+  as type
+- it must behave like a Boost.Range
+- its range value must fulfil the Polygon concept
+
+*/
+template <typename Geometry>
+class MultiPolygon
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+    typedef typename boost::range_value<Geometry>::type polygon_type;
+
+    BOOST_CONCEPT_ASSERT( (concept::Polygon<polygon_type>) );
+    BOOST_CONCEPT_ASSERT( (boost::RandomAccessRangeConcept<Geometry>) );
+
+
+public :
+
+    BOOST_CONCEPT_USAGE(MultiPolygon)
+    {
+    }
+#endif
+};
+
+
+/*!
+\brief concept for multi-polygon (const version)
+\ingroup const_concepts
+*/
+template <typename Geometry>
+class ConstMultiPolygon
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+    typedef typename boost::range_value<Geometry>::type polygon_type;
+
+    BOOST_CONCEPT_ASSERT( (concept::ConstPolygon<polygon_type>) );
+    BOOST_CONCEPT_ASSERT( (boost::RandomAccessRangeConcept<Geometry>) );
+
+
+public :
+
+    BOOST_CONCEPT_USAGE(ConstMultiPolygon)
+    {
+    }
+#endif
+};
+
+}} // namespace ggl::concept
+
+
+#endif // GGL_MULTI_GEOMETRIES_CONCEPTS_MULTI_POLYGON_CONCEPT_HPP
Added: sandbox/ggl/formal_review/boost/ggl/multi/geometries/multi_linestring.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/multi/geometries/multi_linestring.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,63 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_GEOMETRIES_LINESTRING_HPP
+#define GGL_MULTI_GEOMETRIES_LINESTRING_HPP
+
+#include <memory>
+#include <vector>
+
+#include <boost/concept/requires.hpp>
+
+#include <ggl/geometries/concepts/linestring_concept.hpp>
+
+#include <ggl/multi/core/tags.hpp>
+
+namespace ggl
+{
+
+/*!
+    \brief multi_line, a collection of linestring
+    \details Multi-linestring can be used to group lines belonging to each other,
+            e.g. a highway (with interruptions)
+    \ingroup geometries
+*/
+template
+<
+    typename L,
+    template<typename, typename> class V = std::vector,
+    template<typename> class A = std::allocator
+>
+struct multi_linestring : public V<L, A<L> >
+{
+    BOOST_CONCEPT_ASSERT( (concept::Linestring<L>) );
+};
+
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+template
+<
+    typename L,
+    template<typename, typename> class V,
+    template<typename> class A
+>
+struct tag< multi_linestring<L, V, A> >
+{
+    typedef multi_linestring_tag type;
+};
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+
+} // namespace ggl
+
+#endif // GGL_MULTI_GEOMETRIES_LINESTRING_HPP
Added: sandbox/ggl/formal_review/boost/ggl/multi/geometries/multi_point.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/multi/geometries/multi_point.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,61 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_GEOMETRIES_MULTI_POINT_HPP
+#define GGL_MULTI_GEOMETRIES_MULTI_POINT_HPP
+
+#include <memory>
+#include <vector>
+
+#include <boost/concept/requires.hpp>
+
+#include <ggl/geometries/concepts/point_concept.hpp>
+
+#include <ggl/multi/core/tags.hpp>
+
+namespace ggl
+{
+
+/*!
+    \brief multi_point, a collection of points
+    \details Multipoint can be used to group points belonging to each other,
+            e.g. a constellation
+    \ingroup geometries
+*/
+template
+<
+    typename P,
+    template<typename, typename> class V = std::vector,
+    template<typename> class A = std::allocator
+>
+struct multi_point : public V<P, A<P> >
+{
+    BOOST_CONCEPT_ASSERT( (concept::Point<P>) );
+};
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+template
+<
+    typename P,
+    template<typename, typename> class V,
+    template<typename> class A
+>
+struct tag< multi_point<P, V, A> >
+{
+    typedef multi_point_tag type;
+};
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+} // namespace ggl
+
+#endif // GGL_MULTI_GEOMETRIES_MULTI_POINT_HPP
Added: sandbox/ggl/formal_review/boost/ggl/multi/geometries/multi_polygon.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/multi/geometries/multi_polygon.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,61 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_GEOMETRIES_MULTI_POLYGON_HPP
+#define GGL_MULTI_GEOMETRIES_MULTI_POLYGON_HPP
+
+#include <memory>
+#include <vector>
+
+#include <boost/concept/requires.hpp>
+
+#include <ggl/multi/core/tags.hpp>
+
+#include <ggl/geometries/concepts/polygon_concept.hpp>
+
+namespace ggl
+{
+
+/*!
+    \brief multi_polygon, a collection of linestring
+    \details Multi-polygon can be used to group polygons belonging to each other,
+            e.g. Hawaii
+    \ingroup geometries
+*/
+template
+<
+    typename P,
+    template<typename, typename> class V = std::vector,
+    template<typename> class A = std::allocator
+>
+struct multi_polygon : public V<P, A<P> >
+{
+    BOOST_CONCEPT_ASSERT( (concept::Polygon<P>) );
+};
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+template
+<
+    typename P,
+    template<typename, typename> class V,
+    template<typename> class A
+>
+struct tag< multi_polygon<P, V, A> >
+{
+    typedef multi_polygon_tag type;
+};
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+} // namespace ggl
+
+#endif // GGL_MULTI_GEOMETRIES_MULTI_POLYGON_HPP
Added: sandbox/ggl/formal_review/boost/ggl/multi/iterators/range_type.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/multi/iterators/range_type.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,57 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_ITERATORS_RANGE_TYPE_HPP
+#define GGL_MULTI_ITERATORS_RANGE_TYPE_HPP
+
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/multi/core/is_multi.hpp>
+
+#include <ggl/iterators/range_type.hpp>
+
+namespace ggl {
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+// multi-point acts itself as a range
+template <typename Geometry>
+struct range_type<multi_point_tag, Geometry>
+{
+    typedef Geometry type;
+};
+
+
+template <typename Geometry>
+struct range_type<multi_linestring_tag, Geometry>
+{
+    typedef typename boost::range_value<Geometry>::type type;
+};
+
+
+template <typename Geometry>
+struct range_type<multi_polygon_tag, Geometry>
+{
+    // Call its single-version
+    typedef typename ggl::ring_type
+        <
+            typename boost::range_value<Geometry>::type
+        >::type type;
+};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+} // namespace ggl
+
+#endif // GGL_MULTI_ITERATORS_RANGE_TYPE_HPP
Added: sandbox/ggl/formal_review/boost/ggl/multi/multi.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/multi/multi.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,61 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Mateusz Loskot 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_HPP
+#define GGL_MULTI_HPP
+
+
+#include <ggl/multi/core/geometry_id.hpp>
+#include <ggl/multi/core/is_multi.hpp>
+#include <ggl/multi/core/point_type.hpp>
+#include <ggl/multi/core/ring_type.hpp>
+#include <ggl/multi/core/tags.hpp>
+#include <ggl/multi/core/topological_dimension.hpp>
+
+
+#include <ggl/multi/algorithms/area.hpp>
+#include <ggl/multi/algorithms/centroid.hpp>
+#include <ggl/multi/algorithms/convex_hull.hpp>
+#include <ggl/multi/algorithms/correct.hpp>
+#include <ggl/multi/algorithms/distance.hpp>
+#include <ggl/multi/algorithms/envelope.hpp>
+#include <ggl/multi/algorithms/for_each.hpp>
+#include <ggl/multi/algorithms/get_section.hpp>
+#include <ggl/multi/algorithms/intersection.hpp>
+#include <ggl/multi/algorithms/length.hpp>
+#include <ggl/multi/algorithms/num_points.hpp>
+#include <ggl/multi/algorithms/perimeter.hpp>
+#include <ggl/multi/algorithms/sectionalize.hpp>
+#include <ggl/multi/algorithms/simplify.hpp>
+#include <ggl/multi/algorithms/transform.hpp>
+#include <ggl/multi/algorithms/within.hpp>
+#include <ggl/multi/algorithms/detail/modify_with_predicate.hpp>
+#include <ggl/multi/algorithms/detail/multi_sum.hpp>
+#include <ggl/multi/algorithms/overlay/copy_segments.hpp>
+#include <ggl/multi/algorithms/overlay/get_intersection_points.hpp>
+
+
+#include <ggl/multi/geometries/multi_point.hpp>
+#include <ggl/multi/geometries/multi_linestring.hpp>
+#include <ggl/multi/geometries/multi_polygon.hpp>
+#include <ggl/multi/geometries/concepts/check.hpp>
+#include <ggl/multi/geometries/concepts/multi_point_concept.hpp>
+#include <ggl/multi/geometries/concepts/multi_linestring_concept.hpp>
+#include <ggl/multi/geometries/concepts/multi_polygon_concept.hpp>
+
+#include <ggl/multi/iterators/range_type.hpp>
+
+#include <ggl/multi/strategies/centroid.hpp>
+#include <ggl/multi/strategies/cartesian/centroid_average.hpp>
+
+#include <ggl/multi/util/write_dsv.hpp>
+
+
+
+#endif // GGL_MULTI_HPP
Added: sandbox/ggl/formal_review/boost/ggl/multi/strategies/cartesian/centroid_average.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/multi/strategies/cartesian/centroid_average.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,96 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_STRATEGIES_CARTESIAN_CENTROID_AVERAGE_HPP
+#define GGL_MULTI_STRATEGIES_CARTESIAN_CENTROID_AVERAGE_HPP
+
+
+#include <boost/numeric/conversion/cast.hpp>
+#include <boost/type_traits.hpp>
+
+#include <ggl/core/coordinate_type.hpp>
+#include <ggl/core/point_type.hpp>
+#include <ggl/arithmetic/arithmetic.hpp>
+#include <ggl/strategies/centroid.hpp>
+#include <ggl/util/copy.hpp>
+
+
+namespace ggl
+{
+
+namespace strategy { namespace centroid_ {
+
+
+template
+<
+    typename PointCentroid,
+    typename Point = PointCentroid
+>
+class centroid_average
+{
+private :
+
+    /*! subclass to keep state */
+    class sum
+    {
+        friend class centroid_average;
+        int count;
+        PointCentroid centroid;
+
+    public :
+        inline sum()
+            : count(0)
+        {
+            assign_zero(centroid);
+        }
+    };
+
+public :
+    typedef sum state_type;
+    typedef PointCentroid centroid_point_type;
+    typedef Point point_type;
+
+    static inline void apply(Point const& p, sum& state)
+    {
+        add_point(state.centroid, p);
+        state.count++;
+    }
+
+    static inline void result(sum const& state, PointCentroid& centroid)
+    {
+        centroid = state.centroid;
+        divide_value(centroid, state.count);
+    }
+
+};
+
+
+}} // namespace strategy::centroid
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+
+template <typename Point, typename Geometry>
+struct strategy_centroid<cartesian_tag, multi_point_tag, 2, Point, Geometry>
+{
+    typedef strategy::centroid_::centroid_average
+        <
+            Point,
+            typename point_type<Geometry>::type
+        > type;
+};
+
+#endif
+
+
+} // namespace ggl
+
+
+#endif // GGL_MULTI_STRATEGIES_CARTESIAN_CENTROID_AVERAGE_HPP
Added: sandbox/ggl/formal_review/boost/ggl/multi/strategies/centroid.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/multi/strategies/centroid.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,38 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_STRATEGY_CENTROID_HPP
+#define GGL_MULTI_STRATEGY_CENTROID_HPP
+
+#include <ggl/strategies/cartesian/centroid_bashein_detmer.hpp>
+
+
+namespace ggl
+{
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+template <typename Point, typename Geometry>
+struct strategy_centroid<cartesian_tag, multi_polygon_tag, 2, Point, Geometry>
+{
+    typedef strategy::centroid_::bashein_detmer
+        <
+            Point,
+            typename point_type<Geometry>::type
+        > type;
+};
+
+#endif
+
+
+} // namespace ggl
+
+
+#endif // GGL_MULTI_STRATEGY_CENTROID_HPP
Added: sandbox/ggl/formal_review/boost/ggl/multi/util/for_each_range.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/multi/util/for_each_range.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,81 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_UTIL_FOR_EACH_RANGE_HPP
+#define GGL_MULTI_UTIL_FOR_EACH_RANGE_HPP
+
+
+#include <ggl/util/for_each_range.hpp>
+#include <ggl/util/range_iterator_const_if_c.hpp>
+
+#include <ggl/multi/core/tags.hpp>
+
+
+namespace ggl
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace for_each {
+
+
+template <typename Multi, typename Actor, bool IsConst>
+struct fe_range_multi
+{
+    static inline void apply(
+                    typename add_const_if_c<IsConst, Multi>::type& multi,
+                    Actor& actor)
+    {
+        for (typename range_iterator_const_if_c<IsConst, Multi>::type
+                it = boost::begin(multi);
+            it != boost::end(multi);
+            ++it)
+        {
+            ggl::for_each_range(*it, actor);
+        }
+    }
+};
+
+
+
+}} // namespace detail::for_each
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename Geometry, typename Actor, bool IsConst>
+struct for_each_range<multi_linestring_tag, true, Geometry, Actor, IsConst>
+    : detail::for_each::fe_range_multi<Geometry, Actor, IsConst>
+{};
+
+
+template <typename Geometry, typename Actor, bool IsConst>
+struct for_each_range<multi_polygon_tag, true, Geometry, Actor, IsConst>
+    : detail::for_each::fe_range_multi<Geometry, Actor, IsConst>
+{};
+
+
+template <typename MultiPoint, typename Actor, bool IsConst>
+struct for_each_range<multi_point_tag, true, MultiPoint, Actor, IsConst>
+    : detail::for_each::fe_range_range<MultiPoint, Actor, IsConst>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+
+} // namespace ggl
+
+
+#endif // GGL_MULTI_UTIL_FOR_EACH_RANGE_HPP
Added: sandbox/ggl/formal_review/boost/ggl/multi/util/write_dsv.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/multi/util/write_dsv.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,72 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_MULTI_UTIL_WRITE_DSV_HPP
+#define GGL_MULTI_UTIL_WRITE_DSV_HPP
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/util/write_dsv.hpp>
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace dsv {
+
+
+template <typename MultiGeometry>
+struct dsv_multi
+{
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>& os,
+                MultiGeometry const& multi,
+                dsv_settings const& settings)
+    {
+        os << settings.list_open;
+
+        typedef typename boost::range_const_iterator
+            <
+                MultiGeometry
+            >::type iterator;
+        for(iterator it = boost::begin(multi);
+            it != boost::end(multi);
+            ++it)
+        {
+            os << ggl::dsv(*it);
+        }
+        os << settings.list_close;
+    }
+};
+
+
+
+
+}} // namespace detail::dsv
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch {
+
+
+template <typename Tag, typename Geometry>
+struct dsv<Tag, true, Geometry>
+    : detail::dsv::dsv_multi<Geometry>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+
+} // namespace ggl
+
+#endif // GGL_MULTI_UTIL_WRITE_DSV_HPP
Added: sandbox/ggl/formal_review/boost/ggl/policies/compare.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/policies/compare.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,246 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 2009, Geodan, Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_POLICIES_COMPARE_HPP
+#define GGL_POLICIES_COMPARE_HPP
+
+
+/*!
+\defgroup compare compare: define compare functors for points
+\details Useful for:
+- std::map (use ggl::less<P>)
+- std::sort  (use ggl::less<P> or ggl::greater<P> or ggl::less<P, 1>)
+- std::unique_copy (use ggl::equals<P>)
+
+\par Geometries:
+- \b point
+*/
+
+#include <ggl/strategies/compare.hpp>
+#include <ggl/util/math.hpp>
+
+namespace ggl
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace compare {
+
+
+template
+<
+    int Direction,
+    typename Point,
+    typename Strategy,
+    std::size_t Dimension,
+    std::size_t DimensionCount
+>
+struct compare_loop
+{
+    typedef typename strategy::compare::detail::select_strategy
+        <
+            Strategy, Direction, Point, Dimension
+        >::type compare_type;
+
+    typedef typename ggl::coordinate_type<Point>::type coordinate_type;
+
+    static inline bool apply(Point const& left, Point const& right)
+    {
+        coordinate_type const& cleft = ggl::get<Dimension>(left);
+        coordinate_type const& cright = ggl::get<Dimension>(right);
+
+        if (ggl::math::equals(cleft, cright))
+        {
+            return compare_loop
+                <
+                    Direction, Point, Strategy,
+                    Dimension + 1, DimensionCount
+                >::apply(left, right);
+        }
+        else
+        {
+            compare_type compare;
+            return compare(cleft, cright);
+        }
+    }
+};
+
+template
+<
+    int Direction,
+    typename Point,
+    typename Strategy,
+    std::size_t DimensionCount
+>
+struct compare_loop<Direction, Point, Strategy, DimensionCount, DimensionCount>
+{
+    static inline bool apply(Point const&, Point const&)
+    {
+        return false;
+    }
+};
+
+
+template <int Direction, typename Point, typename Strategy>
+struct compare_in_all_dimensions
+{
+    inline bool operator()(Point const& left, Point const& right) const
+    {
+        return detail::compare::compare_loop
+            <
+                Direction, Point, Strategy,
+                0, ggl::dimension<Point>::type::value
+            >::apply(left, right);
+    }
+};
+
+
+template
+<
+    typename Point,
+    typename Strategy,
+    std::size_t Dimension
+>
+class compare_in_one_dimension
+{
+    Strategy compare;
+
+public :
+    inline bool operator()(Point const& left, Point const& right) const
+    {
+        typedef typename ggl::coordinate_type<Point>::type coordinate_type;
+
+        coordinate_type const& cleft = get<Dimension>(left);
+        coordinate_type const& cright = get<Dimension>(right);
+        return compare(cleft, cright);
+    }
+};
+
+}} // namespace detail::compare
+
+#endif
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+    int Direction,
+    typename Point,
+    typename Strategy,
+    int Dimension
+>
+struct compare_geometries
+    : detail::compare::compare_in_one_dimension
+        <
+            Point,
+            typename strategy::compare::detail::select_strategy
+                <
+                    Strategy, Direction, Point, Dimension
+                >::type,
+            Dimension
+        >
+{};
+
+
+// Specialization with -1: compare in all dimensions
+template <int Direction, typename Point, typename Strategy>
+struct compare_geometries<Direction, Point, Strategy, -1>
+    : detail::compare::compare_in_all_dimensions<Direction, Point, Strategy>
+{};
+
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+\brief Less functor, to sort points in ascending order.
+\ingroup compare
+\details This functor compares points and orders them on x,
+    then on y, then on z coordinate.
+\tparam Geometry the geometry
+\tparam Dimension the dimension to sort on, defaults to -1,
+    indicating ALL dimensions. That's to say, first on x,
+    on equal x-es then on y, etc.
+    If a dimension is specified, only that dimension is considered
+\tparam Strategy underlying coordinate comparing functor,
+    defaults to the default comparison strategies
+    related to the point coordinate system. If specified, the specified
+    strategy is used. This can e.g. be std::less<double>.
+*/
+template
+<
+    typename Point,
+    int Dimension = -1,
+    typename Strategy = strategy::compare::default_strategy
+>
+struct less
+    : dispatch::compare_geometries
+        <
+            1, // indicates ascending
+            Point,
+            Strategy,
+            Dimension
+        >
+{};
+
+
+/*!
+\brief Greater functor
+\ingroup compare
+\details Can be used to sort points in reverse order
+\see Less functor
+*/
+template
+<
+    typename Point,
+    int Dimension = -1,
+    typename Strategy = strategy::compare::default_strategy
+>
+struct greater
+    : dispatch::compare_geometries
+        <
+            -1,  // indicates descending
+            Point,
+            Strategy,
+            Dimension
+        >
+{};
+
+
+/*!
+\brief Equal To functor, to compare if points are equal
+\ingroup compare
+\tparam Geometry the geometry
+\tparam Dimension the dimension to compare on, defaults to -1,
+    indicating ALL dimensions.
+    If a dimension is specified, only that dimension is considered
+\tparam Strategy underlying coordinate comparing functor
+*/
+template
+<
+    typename Point,
+    int Dimension = 0,
+    typename Strategy = strategy::compare::default_strategy
+>
+struct equal_to
+    : dispatch::compare_geometries
+        <
+            0,
+            Point,
+            Strategy,
+            Dimension
+        >
+{};
+
+
+} // namespace ggl
+
+#endif // GGL_POLICIES_COMPARE_HPP
Added: sandbox/ggl/formal_review/boost/ggl/policies/relate/direction.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/policies/relate/direction.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,299 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_GEOMETRY_POLICIES_RELATE_DIRECTION_HPP
+#define GGL_GEOMETRY_POLICIES_RELATE_DIRECTION_HPP
+
+#include <boost/concept_check.hpp>
+
+#include <ggl/util/math.hpp>
+#include <ggl/util/select_coordinate_type.hpp>
+
+
+namespace ggl
+{
+
+
+namespace policies { namespace relate {
+
+struct direction_type
+{
+    inline direction_type(char h,
+                double a = 0, double b = 0,
+                int ha = 0, int hb = 0,
+                int da = 0, int db = 0,
+                bool op = false)
+        : how(h)
+        , opposite(op)
+        , ra(a)
+        , rb(b)
+        , how_a(ha)
+        , how_b(hb)
+        , dir_a(da)
+        , dir_b(db)
+    {
+    }
+
+    inline direction_type(char h, bool op, int ha = 0, int hb = 0)
+        : how(h)
+        , opposite(op)
+        , ra(0)
+        , rb(0)
+        , how_a(ha)
+        , how_b(hb)
+        , dir_a(0)
+        , dir_b(0)
+    {
+    }
+
+
+    // "How" is the intersection formed?
+    char how;
+
+    // Is it opposite (for collinear/equal cases)
+    bool opposite;
+
+    // "Distance information", information on how far lies IP from a/b in ratio [0..1]
+    double ra, rb;
+
+    // Information on how A arrives at intersection, how B arrives at intersection
+    // 1: arrives at intersection
+    // -1: starts from intersection
+    int how_a;
+    int how_b;
+
+    // Direction: how is A positioned from B
+    // 1: points left, seen from IP
+    // -1: points right, seen from IP
+    // In case of intersection: B's TO direction
+    // In case that B's TO direction is at A: B's from direction
+    // In collinear cases: it is 0
+    int dir_a; // Direction of A-s TO from IP
+    int dir_b; // Direction of B-s TO from IP
+};
+
+
+template <typename S1, typename S2>
+struct segments_direction
+{
+    typedef direction_type return_type;
+    typedef S1 segment_type1;
+    typedef S2 segment_type2;
+    typedef typename select_coordinate_type<S1, S2>::type coordinate_type;
+
+    static inline return_type rays_intersect(bool on_segment,
+                    double ra, double rb,
+                    coordinate_type const& dx1, coordinate_type const& dy1,
+                    coordinate_type const& dx2, coordinate_type const& dy2,
+                    coordinate_type const& wx, coordinate_type const& wy,
+                    S1 const& s1, S2 const& s2)
+    {
+        boost::ignore_unused_variable_warning(dx2);
+        boost::ignore_unused_variable_warning(dy2);
+        boost::ignore_unused_variable_warning(wx);
+        boost::ignore_unused_variable_warning(wy);
+
+        if(on_segment)
+        {
+            // 0 <= ra <= 1 and 0 <= rb <= 1
+            // Check the configuration
+            bool ra0 = math::equals(ra, 0.0);
+            bool ra1 = math::equals(ra, 1.0);
+            bool rb0 = math::equals(rb, 0.0);
+            bool rb1 = math::equals(rb, 1.0);
+
+            return
+                // opposite and same starting point (FROM)
+                ra0 && rb0 ? calculate_side<1>(ra, rb, dx1, dy1, s1, s2, 'f', -1, -1)
+
+                // opposite and point to each other (TO)
+                : ra1 && rb1 ? calculate_side<0>(ra, rb, dx1, dy1, s1, s2, 't', 1, 1)
+
+                // not opposite, forming an angle, first a then b,
+                // directed either both left, or both right
+                // Check side of B2 from A. This is not calculated before
+                : ra1 && rb0 ? angle<1>(ra, rb, dx1, dy1, s1, s2, 'a', 1, -1)
+
+                // not opposite, forming a angle, first b then a,
+                // directed either both left, or both right
+                : ra0 && rb1 ? angle<0>(ra, rb, dx1, dy1, s1, s2, 'a', -1, 1)
+
+                // b starts from interior of a
+                : rb0 ? starts_from_middle(ra, rb, dx1, dy1, s1, s2, 'B', 0, -1)
+
+                // a starts from interior of b (#39)
+                : ra0 ? starts_from_middle(ra, rb, dx1, dy1, s1, s2, 'A', -1, 0)
+
+                // b ends at interior of a, calculate direction of A from IP
+                : rb1 ? b_ends_at_middle(ra, rb, dx2, dy2, s1, s2)
+
+                // a ends at interior of b
+                : ra1 ? a_ends_at_middle(ra, rb, dx1, dy1, s1, s2)
+
+                // normal intersection
+                : calculate_side<1>(ra, rb, dx1, dy1, s1, s2, 'i', -1, -1)
+                ;
+        }
+
+        // Not on segment, disjoint
+        return return_type('d');
+    }
+
+    static inline return_type collinear_touch(coordinate_type const& , coordinate_type const& , bool opposite, char how)
+    {
+        // Though this is 'collinear', we handle it as To/From/Angle because it is the same.
+        // It only does NOT have a direction.
+        int const arrive = how == 'T' ? 1 : -1;
+        return
+            ! opposite
+            ? return_type('a', 0, 0, how == 'A' ? 1 : -1, how == 'B' ? 1 : -1)
+            : return_type(how == 'T' ? 't' : 'f', 0, 0, arrive, arrive, 0, 0, true);
+    }
+
+    template <typename S>
+    static inline return_type collinear_interior_boundary_intersect(S const& , bool, bool opposite)
+    {
+        return return_type('c', opposite);
+    }
+
+    static inline return_type collinear_a_in_b(S1 const& , bool opposite)
+    {
+        return return_type('c', opposite);
+    }
+    static inline return_type collinear_b_in_a(S2 const& , bool opposite)
+    {
+        return return_type('c', opposite);
+    }
+
+    static inline return_type collinear_overlaps(
+                    coordinate_type const& , coordinate_type const& ,
+                    coordinate_type const& , coordinate_type const& , bool opposite)
+    {
+        return return_type('c', opposite);
+    }
+
+    static inline return_type segment_equal(S1 const& , bool opposite)
+    {
+        return return_type('e', opposite);
+    }
+
+    static inline return_type degenerate(S1 const& , bool)
+    {
+        return return_type('0');
+    }
+
+    static inline return_type collinear_disjoint()
+    {
+        return return_type('d');
+    }
+
+
+    static inline return_type parallel()
+    {
+        return return_type('p');
+    }
+
+private :
+
+
+    template <std::size_t I>
+    static inline return_type calculate_side(double ra, double rb,
+                coordinate_type const& dx1, coordinate_type const& dy1,
+                S1 const& s1, S2 const& s2,
+                char how, int how_a, int how_b)
+    {
+        coordinate_type dpx = get<I, 0>(s2) - get<0, 0>(s1);
+        coordinate_type dpy = get<I, 1>(s2) - get<0, 1>(s1);
+
+        // This is a "side calculation" as in the strategies, but here two terms are precalculated
+        // We might merge this with side, offering a pre-calculated term
+        // Waiting for implementing spherical...
+
+        return dx1 * dpy - dy1 * dpx > 0
+            ? return_type(how, ra, rb, how_a, how_b, -1, 1)
+            : return_type(how, ra, rb, how_a, how_b, 1, -1);
+    }
+
+    template <std::size_t I>
+    static inline return_type angle(double ra, double rb,
+                coordinate_type const& dx1, coordinate_type const& dy1,
+                S1 const& s1, S2 const& s2,
+                char how, int how_a, int how_b)
+    {
+        coordinate_type dpx = get<I, 0>(s2) - get<0, 0>(s1);
+        coordinate_type dpy = get<I, 1>(s2) - get<0, 1>(s1);
+
+         return dx1 * dpy - dy1 * dpx > 0
+            ? return_type(how, ra, rb, how_a, how_b, 1, 1)
+            : return_type(how, ra, rb, how_a, how_b, -1, -1);
+    }
+
+
+    static inline return_type starts_from_middle(double ra, double rb,
+                coordinate_type const& dx1, coordinate_type const& dy1,
+                S1 const& s1, S2 const& s2,
+                char which,
+                int how_a, int how_b)
+    {
+        // Calculate ARROW of b segment w.r.t. s1
+        coordinate_type dpx = get<1, 0>(s2) - get<0, 0>(s1);
+        coordinate_type dpy = get<1, 1>(s2) - get<0, 1>(s1);
+
+        int dir = dx1 * dpy - dy1 * dpx > 0 ? 1 : -1;
+
+        // From other perspective, then reverse
+        bool const is_a = which == 'A';
+        if (is_a)
+        {
+            dir = -dir;
+        }
+
+        return return_type('s', ra, rb,
+            how_a,
+            how_b,
+            is_a ? dir : -dir,
+            ! is_a ? dir : -dir);
+    }
+
+
+
+    // To be harmonized
+    static inline return_type a_ends_at_middle(double ra, double rb,
+                coordinate_type const& dx, coordinate_type const& dy,
+                S1 const& s1, S2 const& s2)
+    {
+        coordinate_type dpx = get<1, 0>(s2) - get<0, 0>(s1);
+        coordinate_type dpy = get<1, 1>(s2) - get<0, 1>(s1);
+
+        // Ending at the middle, one ARRIVES, the other one is NEUTRAL
+        // (because it both "arrives"  and "departs"  there
+        return dx * dpy - dy * dpx > 0
+            ? return_type('m', ra, rb, 1, 0, 1, 1)
+            : return_type('m', ra, rb, 1, 0, -1, -1);
+    }
+
+
+    static inline return_type b_ends_at_middle(double ra, double rb,
+                coordinate_type const& dx, coordinate_type const& dy,
+                S1 const& s1, S2 const& s2)
+    {
+        coordinate_type dpx = get<1, 0>(s1) - get<0, 0>(s2);
+        coordinate_type dpy = get<1, 1>(s1) - get<0, 1>(s2);
+
+        return dx * dpy - dy * dpx > 0
+            ? return_type('m', ra, rb, 0, 1, 1, 1)
+            : return_type('m', ra, rb, 0, 1, -1, -1);
+    }
+
+};
+
+}} // namespace policies::relate
+
+} // namespace ggl
+
+#endif // GGL_GEOMETRY_POLICIES_RELATE_DIRECTION_HPP
Added: sandbox/ggl/formal_review/boost/ggl/policies/relate/intersection_points.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/policies/relate/intersection_points.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,143 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_GEOMETRY_POLICIES_RELATE_INTERSECTION_POINTS_HPP
+#define GGL_GEOMETRY_POLICIES_RELATE_INTERSECTION_POINTS_HPP
+
+#include <boost/concept_check.hpp>
+
+#include <ggl/core/access.hpp>
+#include <ggl/util/select_coordinate_type.hpp>
+
+
+namespace ggl
+{
+
+namespace policies { namespace relate {
+
+
+template <typename S1, typename S2, typename ReturnType>
+struct segments_intersection_points
+{
+    typedef ReturnType return_type;
+    typedef S1 segment_type1;
+    typedef S2 segment_type2;
+    typedef typename select_coordinate_type<S1, S2>::type coordinate_type;
+
+    static inline return_type rays_intersect(bool on_segment,
+                    double ra, double rb,
+                    coordinate_type const& dx1, coordinate_type const& dy1,
+                    coordinate_type const& dx2, coordinate_type const& dy2,
+                    coordinate_type const& wx, coordinate_type const& wy,
+                    S1 const& s1, S2 const& s2)
+    {
+        boost::ignore_unused_variable_warning(rb);
+        boost::ignore_unused_variable_warning(dx2);
+        boost::ignore_unused_variable_warning(dy2);
+        boost::ignore_unused_variable_warning(wx);
+        boost::ignore_unused_variable_warning(wy);
+        boost::ignore_unused_variable_warning(s2);
+
+        return_type result;
+
+        if (on_segment)
+        {
+            result.count = 1;
+            set<0>(result.intersections[0],
+                boost::numeric_cast<coordinate_type>(get<0, 0>(s1) + ra * dx1));
+            set<1>(result.intersections[0],
+                boost::numeric_cast<coordinate_type>(get<0, 1>(s1) + ra * dy1));
+        }
+        return result;
+    }
+
+    static inline return_type collinear_touch(coordinate_type const& x,
+                coordinate_type const& y, bool, char)
+    {
+        return_type result;
+        result.count = 1;
+        set<0>(result.intersections[0], x);
+        set<1>(result.intersections[0], y);
+        return result;
+    }
+
+    template <typename S>
+    static inline return_type collinear_inside(S const& s)
+    {
+        return_type result;
+        result.count = 2;
+        set<0>(result.intersections[0], get<0, 0>(s));
+        set<1>(result.intersections[0], get<0, 1>(s));
+        set<0>(result.intersections[1], get<1, 0>(s));
+        set<1>(result.intersections[1], get<1, 1>(s));
+        return result;
+    }
+
+    template <typename S>
+    static inline return_type collinear_interior_boundary_intersect(S const& s, bool, bool)
+    {
+        return collinear_inside(s);
+    }
+
+    static inline return_type collinear_a_in_b(S1 const& s, bool)
+    {
+        return collinear_inside(s);
+    }
+    static inline return_type collinear_b_in_a(S2 const& s, bool)
+    {
+        return collinear_inside(s);
+    }
+
+    static inline return_type collinear_overlaps(
+                coordinate_type const& x1, coordinate_type const& y1,
+                coordinate_type const& x2, coordinate_type const& y2, bool)
+    {
+        return_type result;
+        result.count = 2;
+        set<0>(result.intersections[0], x1);
+        set<1>(result.intersections[0], y1);
+        set<0>(result.intersections[1], x2);
+        set<1>(result.intersections[1], y2);
+        return result;
+    }
+
+    static inline return_type segment_equal(S1 const& s, bool)
+    {
+        return_type result;
+        result.count = 2;
+        set<0>(result.intersections[0], get<0, 0>(s));
+        set<1>(result.intersections[0], get<0, 1>(s));
+        set<0>(result.intersections[1], get<1, 0>(s));
+        set<1>(result.intersections[1], get<1, 1>(s));
+        return result;
+    }
+
+    static inline return_type collinear_disjoint()
+    {
+        return return_type();
+    }
+    static inline return_type parallel()
+    {
+        return return_type();
+    }
+    static inline return_type degenerate(S1 const& s, bool)
+    {
+        return_type result;
+        result.count = 1;
+        set<0>(result.intersections[0], get<0, 0>(s));
+        set<1>(result.intersections[0], get<0, 1>(s));
+        return result;
+    }
+};
+
+
+}} // namespace policies::relate
+
+} // namespace ggl
+
+#endif // GGL_GEOMETRY_POLICIES_RELATE_INTERSECTION_POINTS_HPP
Added: sandbox/ggl/formal_review/boost/ggl/policies/relate/tupled.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/policies/relate/tupled.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,154 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_GEOMETRY_POLICIES_RELATE_TUPLED_HPP
+#define GGL_GEOMETRY_POLICIES_RELATE_TUPLED_HPP
+
+#include <boost/tuple/tuple.hpp>
+#include <ggl/util/select_coordinate_type.hpp>
+
+namespace ggl
+{
+
+namespace policies { namespace relate {
+
+
+// "tupled" to return intersection results together.
+// Now with two, with some meta-programming and derivations it can also be three (or more)
+template <typename Policy1, typename Policy2>
+struct segments_tupled
+{
+    typedef boost::tuple
+        <
+            typename Policy1::return_type,
+            typename Policy2::return_type
+        > return_type;
+
+    // Take segments of first policy, they should be equal
+    typedef typename Policy1::segment_type1 segment_type1;
+    typedef typename Policy1::segment_type2 segment_type2;
+
+    typedef typename select_coordinate_type
+        <
+            segment_type1,
+            segment_type2
+        >::type coordinate_type;
+
+
+    static inline return_type rays_intersect(bool on_segment,
+                    double ra, double rb,
+                    coordinate_type const& dx1, coordinate_type const& dy1,
+                    coordinate_type const& dx2, coordinate_type const& dy2,
+                    coordinate_type const& wx, coordinate_type const& wy,
+                    segment_type1 const& s1, segment_type2 const& s2)
+    {
+        return boost::make_tuple
+            (
+                Policy1::rays_intersect(on_segment, ra, rb, dx1, dy1, dx2, dy2, wx, wy, s1, s2),
+                Policy2::rays_intersect(on_segment, ra, rb, dx1, dy1, dx2, dy2, wx, wy, s1, s2)
+            );
+    }
+
+    static inline return_type collinear_touch(coordinate_type const& x,
+                coordinate_type const& y, bool opposite, char how)
+    {
+        return boost::make_tuple
+            (
+                Policy1::collinear_touch(x, y, opposite, how),
+                Policy2::collinear_touch(x, y, opposite, how)
+            );
+    }
+
+    template <typename S>
+    static inline return_type collinear_interior_boundary_intersect(S const& segment,
+                bool a_within_b, bool opposite)
+    {
+        return boost::make_tuple
+            (
+                Policy1::collinear_interior_boundary_intersect(segment, a_within_b, opposite),
+                Policy2::collinear_interior_boundary_intersect(segment, a_within_b, opposite)
+            );
+    }
+
+    static inline return_type collinear_a_in_b(segment_type1 const& segment,
+                bool opposite)
+    {
+        return boost::make_tuple
+            (
+                Policy1::collinear_a_in_b(segment, opposite),
+                Policy2::collinear_a_in_b(segment, opposite)
+            );
+    }
+    static inline return_type collinear_b_in_a(segment_type2 const& segment,
+                    bool opposite)
+    {
+        return boost::make_tuple
+            (
+                Policy1::collinear_b_in_a(segment, opposite),
+                Policy2::collinear_b_in_a(segment, opposite)
+            );
+    }
+
+
+    static inline return_type collinear_overlaps(
+                    coordinate_type const& x1, coordinate_type const& y1,
+                    coordinate_type const& x2, coordinate_type const& y2,
+                    bool opposite)
+    {
+        return boost::make_tuple
+            (
+                Policy1::collinear_overlaps(x1, y1, x2, y2, opposite),
+                Policy2::collinear_overlaps(x1, y1, x2, y2, opposite)
+            );
+    }
+
+    static inline return_type segment_equal(segment_type1 const& s,
+                bool opposite)
+    {
+        return boost::make_tuple
+            (
+                Policy1::segment_equal(s, opposite),
+                Policy2::segment_equal(s, opposite)
+            );
+    }
+
+    static inline return_type degenerate(segment_type1 const& segment,
+                bool a_degenerate)
+    {
+        return boost::make_tuple
+            (
+                Policy1::degenerate(segment, a_degenerate),
+                Policy2::degenerate(segment, a_degenerate)
+            );
+    }
+
+    static inline return_type collinear_disjoint()
+    {
+        return boost::make_tuple
+            (
+                Policy1::collinear_disjoint(),
+                Policy2::collinear_disjoint()
+            );
+    }
+
+
+    static inline return_type parallel()
+    {
+        return boost::make_tuple
+            (
+                Policy1::parallel(),
+                Policy2::parallel()
+            );
+    }
+};
+
+}} // namespace policies::relate
+
+} // namespace ggl
+
+#endif // GGL_GEOMETRY_POLICIES_RELATE_TUPLED_HPP
Added: sandbox/ggl/formal_review/boost/ggl/strategies/agnostic/hull_graham_andrew.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/strategies/agnostic/hull_graham_andrew.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,387 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 2009, Geodan, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGIES_AGNOSTIC_CONVEX_GRAHAM_ANDREW_HPP
+#define GGL_STRATEGIES_AGNOSTIC_CONVEX_GRAHAM_ANDREW_HPP
+
+
+#include <cstddef>
+#include <algorithm>
+#include <vector>
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/core/cs.hpp>
+#include <ggl/core/point_type.hpp>
+#include <ggl/strategies/convex_hull.hpp>
+
+#include <ggl/iterators/range_type.hpp>
+
+#include <ggl/policies/compare.hpp>
+
+#include <ggl/util/for_each_range.hpp>
+
+
+// Temporary, comparing tests, this can be removed in the end
+#if defined(GGL_USE_SMOOTH_SORT)
+#  include "SmoothSort.hpp"
+#elif defined(GGL_USE_MERGE_SORT)
+#  include "MergeSort.hpp"
+#else
+#endif
+
+namespace ggl
+{
+
+namespace strategy { namespace convex_hull {
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+
+template
+<
+    typename InputRange,
+    typename RangeIterator,
+    typename StrategyLess,
+    typename StrategyGreater
+>
+struct get_extremes
+{
+    typedef typename point_type<InputRange>::type point_type;
+
+    point_type left, right;
+
+    bool first;
+
+    StrategyLess less;
+    StrategyGreater greater;
+
+    get_extremes()
+        : first(true)
+    {}
+
+    inline void apply(InputRange const& range)
+    {
+        // First iterate through this range
+        // (this two-stage approach avoids many point copies,
+        //  because iterators are kept in memory. Because iterators are
+        //  not persistent (in MSVC) this approach is not applicable
+        //  for more ranges together)
+
+        RangeIterator left_it = boost::begin(range);
+        RangeIterator right_it = boost::begin(range);
+
+        for (RangeIterator it = boost::begin(range) + 1;
+            it != boost::end(range);
+            ++it)
+        {
+            if (less(*it, *left_it))
+            {
+                left_it = it;
+            }
+
+            if (greater(*it, *right_it))
+            {
+                right_it = it;
+            }
+        }
+
+        // Then compare with earlier
+        if (first && boost::size(range) > 0)
+        {
+            // First time, assign left/right
+            left = *left_it;
+            right = *right_it;
+            first = false;
+        }
+        else
+        {
+            // Next time, check if this range was left/right from
+            // the extremes already collected
+            if (less(*left_it, left))
+            {
+                left = *left_it;
+            }
+
+            if (greater(*right_it, right))
+            {
+                right = *right_it;
+            }
+        }
+    }
+};
+
+
+template
+<
+    typename InputRange,
+    typename RangeIterator,
+    typename Container,
+    typename SideStrategy
+>
+struct assign_range
+{
+    Container lower_points, upper_points;
+
+    typedef typename point_type<InputRange>::type point_type;
+
+    point_type const& most_left;
+    point_type const& most_right;
+
+    inline assign_range(point_type const& left, point_type const& right)
+        : most_left(left)
+        , most_right(right)
+    {}
+
+    inline void apply(InputRange const& range)
+    {
+        typedef SideStrategy side;
+
+        // Put points in one of the two output sequences
+        for (RangeIterator it = boost::begin(range);
+            it != boost::end(range);
+            ++it)
+        {
+            // check if it is lying most_left or most_right from the line
+
+            int dir = side::apply(most_left, most_right, *it);
+            switch(dir)
+            {
+                case 1 : // left side
+                    upper_points.push_back(*it);
+                    break;
+                case -1 : // right side
+                    lower_points.push_back(*it);
+                    break;
+
+                // 0: on line most_left-most_right,
+                //    or most_left, or most_right,
+                //    -> all never part of hull
+            }
+        }
+    }
+};
+
+
+template <typename Range>
+static inline void sort(Range& range)
+{
+    typedef typename boost::range_value<Range>::type point_type;
+
+#if defined(USE_SMOOTH_SORT)
+    smoothsort::sort
+#elif defined(USE_MERGE_SORT)
+    comparing::merge_sort<thread_count>
+#else
+    std::sort
+#endif
+
+        (boost::begin(range), boost::end(range), ggl::less<point_type>());
+}
+
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+/*!
+    \brief Graham scan strategy to calculate convex hull
+    \ingroup convex_hull
+    \note Completely reworked version inspired on the sources listed below
+    \see http://www.ddj.com/architect/201806315
+    \see http://marknelson.us/2007/08/22/convex
+
+ */
+template <typename InputGeometry, typename OutputPoint>
+class graham_andrew
+{
+public :
+    typedef OutputPoint point_type;
+    typedef InputGeometry geometry_type;
+
+private:
+
+    typedef typename cs_tag<point_type>::type cs_tag;
+
+    typedef typename std::vector<point_type> container_type;
+    typedef typename std::vector<point_type>::const_iterator iterator;
+    typedef typename std::vector<point_type>::const_reverse_iterator rev_iterator;
+
+
+    class partitions
+    {
+        friend class graham_andrew;
+
+        container_type m_lower_hull;
+        container_type m_upper_hull;
+        container_type m_copied_input;
+    };
+
+
+public:
+    typedef partitions state_type;
+
+
+    inline void apply(InputGeometry const& geometry, partitions& state) const
+    {
+        // First pass.
+        // Get min/max (in most cases left / right) points
+        // This makes use of the ggl::less/greater predicates with the optional
+        // direction template parameter to indicate x direction
+
+        typedef typename range_type<InputGeometry>::type range_type;
+
+        typedef typename boost::range_const_iterator
+            <
+                range_type
+            >::type range_iterator;
+
+        detail::get_extremes
+            <
+                range_type,
+                range_iterator,
+                ggl::less<point_type, 0>,
+                ggl::greater<point_type, 0>
+            > extremes;
+        ggl::for_each_range(geometry, extremes);
+
+        // Bounding left/right points
+        // Second pass, now that extremes are found, assign all points
+        // in either lower, either upper
+        detail::assign_range
+            <
+                range_type,
+                range_iterator,
+                container_type,
+                typename strategy_side<cs_tag>::type
+            > assigner(extremes.left, extremes.right);
+
+        ggl::for_each_range(geometry, assigner);
+
+
+        // Sort both collections, first on x(, then on y)
+        detail::sort(assigner.lower_points);
+        detail::sort(assigner.upper_points);
+
+        // And decide which point should be in the final hull
+        build_half_hull<-1>(assigner.lower_points, state.m_lower_hull,
+                extremes.left, extremes.right);
+        build_half_hull<1>(assigner.upper_points, state.m_upper_hull,
+                extremes.left, extremes.right);
+    }
+
+
+    template <typename OutputIterator>
+    inline void result(partitions const& state,
+                    OutputIterator out, bool clockwise)  const
+    {
+        if (clockwise)
+        {
+            get_range_forward(state.m_upper_hull, out);
+            get_range_reverse(state.m_lower_hull, out);
+        }
+        else
+        {
+            get_range_forward(state.m_lower_hull, out);
+            get_range_reverse(state.m_upper_hull, out);
+        }
+    }
+
+
+private:
+
+    template <int Factor>
+    static inline void build_half_hull(container_type const& input,
+            container_type& output,
+            point_type const& left, point_type const& right)
+    {
+        output.push_back(left);
+        for(iterator it = input.begin(); it != input.end(); ++it)
+        {
+            add_to_hull<Factor>(*it, output);
+        }
+        add_to_hull<Factor>(right, output);
+    }
+
+
+    template <int Factor>
+    static inline void add_to_hull(point_type const& p, container_type& output)
+    {
+        typedef typename strategy_side<cs_tag>::type side;
+
+        output.push_back(p);
+        register std::size_t output_size = output.size();
+        while (output_size >= 3)
+        {
+            rev_iterator rit = output.rbegin();
+            point_type const& last = *rit++;
+            point_type const& last2 = *rit++;
+
+            if (Factor * side::apply(*rit, last, last2) <= 0)
+            {
+                // Remove last two points from stack, and add last again
+                // This is much faster then erasing the one but last.
+                output.pop_back();
+                output.pop_back();
+                output.push_back(last);
+                output_size--;
+            }
+            else
+            {
+                return;
+            }
+        }
+    }
+
+
+    template <typename OutputIterator>
+    static inline void get_range_forward(container_type const& range, OutputIterator out)
+    {
+        for (iterator it = boost::begin(range);
+            it != boost::end(range);
+            ++it, ++out)
+        {
+            *out = *it;
+        }
+    }
+
+
+    template <typename OutputIterator>
+    static inline void get_range_reverse(container_type const& range, OutputIterator out)
+    {
+        // STL Port does not accept iterating from rbegin+1 to rend
+        std::size_t size = range.size();
+        if (size > 0)
+        {
+            rev_iterator it = range.rbegin() + 1;
+            for (std::size_t i = 1; i < size; ++i, ++it, ++out)
+            {
+                *out = *it;
+            }
+        }
+    }
+
+};
+
+}} // namespace strategy::convex_hull
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+template <typename InputGeometry, typename OutputPoint>
+struct strategy_convex_hull<cartesian_tag, InputGeometry, OutputPoint>
+{
+    typedef strategy::convex_hull::graham_andrew<InputGeometry, OutputPoint> type;
+};
+#endif
+
+} // namespace ggl
+
+
+#endif // GGL_STRATEGIES_AGNOSTIC_CONVEX_GRAHAM_ANDREW_HPP
Added: sandbox/ggl/formal_review/boost/ggl/strategies/agnostic/point_in_poly_winding.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/strategies/agnostic/point_in_poly_winding.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,189 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGY_AGNOSTIC_POINT_IN_POLY_WINDING_HPP
+#define GGL_STRATEGY_AGNOSTIC_POINT_IN_POLY_WINDING_HPP
+
+
+
+#include <ggl/util/select_calculation_type.hpp>
+
+#include <ggl/strategies/point_in_poly.hpp>
+
+
+
+namespace ggl
+{
+
+namespace strategy { namespace within {
+
+/*!
+    \brief Within detection using winding rule
+    \tparam Point point type of point to examine
+    \tparam PointOfSegment point type of segments, defaults to Point
+    \author Barend Gehrels
+    \note The implementation is inspired by terralib http://www.terralib.org (LGPL)
+    \note but totally revised afterwards, especially for cases on segments
+    \note Only dependant on "side", -> agnostic, suitable for spherical/latlong
+ */
+template
+<
+    typename Point,
+    typename PointOfSegment = Point,
+    typename CalculationType = void
+>
+class winding
+{
+    typedef typename select_calculation_type
+        <
+            Point,
+            PointOfSegment,
+            CalculationType
+        >::type calculation_type;
+
+
+    typedef typename strategy_side
+        <
+            typename cs_tag<Point>::type
+        >::type strategy_side_type;
+
+
+    /*! subclass to keep state */
+    class counter
+    {
+        int count;
+        bool touches;
+
+        inline bool within_no_touch() const
+        {
+            return ! touches && count != 0;
+        }
+    public :
+        friend class winding;
+
+        inline counter()
+            : count(0)
+            , touches(false)
+        {}
+
+    };
+
+
+    template <size_t D>
+    static inline int check_touch(Point const& point,
+                PointOfSegment const& seg1, PointOfSegment const& seg2,
+                counter& state)
+    {
+        calculation_type const p = get<D>(point);
+        calculation_type const s1 = get<D>(seg1);
+        calculation_type const s2 = get<D>(seg2);
+        if ((s1 <= p && s2 >= p) || (s2 <= p && s1 >= p))
+        {
+            state.touches = true;
+        }
+        return 0;
+    }
+
+
+    template <size_t D>
+    static inline int check_segment(Point const& point,
+                PointOfSegment const& seg1, PointOfSegment const& seg2,
+                counter& state)
+    {
+        calculation_type const p = get<D>(point);
+        calculation_type const s1 = get<D>(seg1);
+        calculation_type const s2 = get<D>(seg2);
+
+        // Check if one of segment endpoints is at same level of point
+        bool eq1 = math::equals(s1, p);
+        bool eq2 = math::equals(s2, p);
+
+        if (eq1 && eq2)
+        {
+            // Both equal p -> segment is horizontal (or vertical for D=0)
+            // The only thing which has to be done is check if point is ON segment
+            return check_touch<1 - D>(point, seg1, seg2,state);
+        }
+
+        return
+              eq1 ? (s2 > p ?  1 : -1)  // Point on level s1, UP/DOWN depending on s2
+            : eq2 ? (s1 > p ? -1 :  1)  // idem
+            : s1 < p && s2 > p ?  2     // Point between s1 -> s2 --> UP
+            : s2 < p && s1 > p ? -2     // Point between s2 -> s1 --> DOWN
+            : 0;
+    }
+
+
+
+
+public :
+
+    // Typedefs and static methods to fulfill the concept
+    typedef Point point_type;
+    typedef PointOfSegment segment_point_type;
+    typedef counter state_type;
+
+    static inline bool apply(Point const& point,
+                PointOfSegment const& s1, PointOfSegment const& s2,
+                counter& state)
+    {
+        int count = check_segment<1>(point, s1, s2, state);
+        if (count != 0)
+        {
+            int side = strategy_side_type::apply(s1, s2, point);
+            if (side == 0)
+            {
+                // Point is lying on segment
+                state.touches = true;
+                state.count = 0;
+                return false;
+            }
+
+            // Side is NEG for right, POS for left.
+            // The count is -2 for down, 2 for up (or -1/1)
+            // Side positive thus means UP and LEFTSIDE or DOWN and RIGHTSIDE
+            // See accompagnying figure (TODO)
+            if (side * count > 0)
+            {
+                state.count += count;
+            }
+
+        }
+        return ! state.touches;
+    }
+
+    static inline bool result(counter const& state)
+    {
+        return state.within_no_touch();
+    }
+};
+
+}} // namespace strategy::within
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+template <typename Point, typename PointOfSegment>
+struct strategy_within<cartesian_tag, cartesian_tag, Point, PointOfSegment>
+{
+    typedef strategy::within::winding<Point, PointOfSegment> type;
+};
+
+template <typename Point, typename PointOfSegment>
+struct strategy_within<geographic_tag, geographic_tag, Point, PointOfSegment>
+{
+    typedef strategy::within::winding<Point, PointOfSegment> type;
+};
+
+#endif
+
+
+} // namespace ggl
+
+
+#endif // GGL_STRATEGY_AGNOSTIC_POINT_IN_POLY_WINDING_HPP
Added: sandbox/ggl/formal_review/boost/ggl/strategies/agnostic/simplify_douglas_peucker.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/strategies/agnostic/simplify_douglas_peucker.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,216 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGY_AGNOSTIC_SIMPLIFY_DOUGLAS_PEUCKER_HPP
+#define GGL_STRATEGY_AGNOSTIC_SIMPLIFY_DOUGLAS_PEUCKER_HPP
+
+#include <vector>
+#include <boost/range/functions.hpp>
+
+#include <ggl/core/cs.hpp>
+#include <ggl/strategies/distance_result.hpp>
+#include <ggl/util/copy.hpp>
+
+
+//#define GL_DEBUG_DOUGLAS_PEUCKER
+
+#ifdef GL_DEBUG_DOUGLAS_PEUCKER
+#include <ggl/util/write_dsv.hpp>
+#endif
+
+
+namespace ggl
+{
+
+namespace strategy { namespace simplify {
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+    /*!
+        \brief Small wrapper around a point, with an extra member "included"
+        \details
+            It has a const-reference to the original point (so no copy here)
+        \tparam the enclosed point type
+    */
+    template<typename Point>
+    struct douglas_peucker_point
+    {
+        Point const& p;
+        bool included;
+
+        inline douglas_peucker_point(Point const& ap)
+            : p(ap)
+            , included(false)
+        {}
+
+        // Necessary for proper compilation
+        inline douglas_peucker_point<Point> operator=(
+                    douglas_peucker_point<Point> const& other)
+        {
+            return douglas_peucker_point<Point>(*this);
+        }
+    };
+}
+#endif // DOXYGEN_NO_DETAIL
+
+
+/*!
+    \brief Implements the simplify algorithm.
+    \ingroup simplify
+    \details The douglas_peucker strategy simplifies a linestring, ring or
+        vector of points using the well-known Douglas-Peucker algorithm.
+        For the algorithm, see for example:
+    \see http://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm
+    \see http://www2.dcs.hull.ac.uk/CISRG/projects/Royal-Inst/demos/dp.html
+    \tparam Point the point type
+    \tparam PointDistanceStrategy point-segment distance strategy to be used
+    \note This strategy uses itself a point-segment-distance strategy which
+        can be specified
+    \author Barend and Maarten, 1995/1996
+    \author Barend, revised for Generic Geometry Library, 2008
+*/
+template
+<
+    typename Point,
+    typename PointDistanceStrategy
+>
+class douglas_peucker
+{
+    typedef detail::douglas_peucker_point<Point> dp_point_type;
+    typedef typename std::vector<dp_point_type>::iterator iterator_type;
+
+    typedef typename PointDistanceStrategy::return_type return_type;
+
+    static inline void consider(iterator_type begin,
+                iterator_type end,
+                return_type const& max_dist, int& n,
+                PointDistanceStrategy const& ps_distance_strategy)
+    {
+        std::size_t size = end - begin;
+
+        // size must be at least 3
+        // because we want to consider a candidate point in between
+        if (size <= 2)
+        {
+#ifdef GL_DEBUG_DOUGLAS_PEUCKER
+            if (begin != end)
+            {
+                std::cout << "ignore between " << dsv(begin->p)
+                    << " and " << dsv((end - 1)->p)
+                    << " size=" << size << std::endl;
+            }
+            std::cout << "return because size=" << size << std::endl;
+#endif
+            return;
+        }
+
+        iterator_type last = end - 1;
+
+#ifdef GL_DEBUG_DOUGLAS_PEUCKER
+        std::cout << "find between " << dsv(begin->p)
+            << " and " << dsv(last->p)
+            << " size=" << size << std::endl;
+#endif
+
+
+        // Find most distance point, compare to the current segment
+        //ggl::segment<const Point> s(begin->p, last->p);
+        return_type md(-1.0); // any value < 0
+        iterator_type candidate;
+        for(iterator_type it = begin + 1; it != last; ++it)
+        {
+            return_type dist = ps_distance_strategy.apply(it->p, begin->p, last->p);
+
+#ifdef GL_DEBUG_DOUGLAS_PEUCKER
+            std::cout << "consider " << dsv(it->p)
+                << " at " << double(dist)
+                << ((dist > max_dist) ? " maybe" : " no")
+                << std::endl;
+
+#endif
+            if (dist > md)
+            {
+                md = dist;
+                candidate = it;
+            }
+        }
+
+        // If a point is found, set the include flag
+        // and handle segments in between recursively
+        if (md > max_dist)
+        {
+#ifdef GL_DEBUG_DOUGLAS_PEUCKER
+            std::cout << "use " << dsv(candidate->p) << std::endl;
+#endif
+
+            candidate->included = true;
+            n++;
+
+            consider(begin, candidate + 1, max_dist, n, ps_distance_strategy);
+            consider(candidate, end, max_dist, n, ps_distance_strategy);
+        }
+    }
+
+
+public :
+
+    typedef PointDistanceStrategy distance_strategy_type;
+
+
+    template <typename Range, typename OutputIterator>
+    static inline OutputIterator apply(Range const& range,
+                    OutputIterator out, double max_distance)
+    {
+        PointDistanceStrategy strategy;
+
+        // Copy coordinates, a vector of references to all points
+        std::vector<dp_point_type> ref_candidates(boost::begin(range),
+                        boost::end(range));
+
+        // Include first and last point of line,
+        // they are always part of the line
+        int n = 2;
+        ref_candidates.front().included = true;
+        ref_candidates.back().included = true;
+
+        // Get points, recursively, including them if they are further away
+        // than the specified distance
+        typedef typename PointDistanceStrategy::return_type return_type;
+
+        consider(boost::begin(ref_candidates), boost::end(ref_candidates),
+            make_distance_result<return_type>(max_distance), n, strategy);
+
+        // Copy included elements to the output
+        for(typename std::vector<dp_point_type>::const_iterator it
+                        = boost::begin(ref_candidates);
+            it != boost::end(ref_candidates);
+            ++it)
+        {
+            if (it->included)
+            {
+                // copy-coordinates does not work because OutputIterator
+                // does not model Point (??)
+                //ggl::copy_coordinates(it->p, *out);
+                *out = it->p;
+                out++;
+            }
+        }
+        return out;
+    }
+
+};
+
+}} // namespace strategy::simplify
+
+
+} // namespace ggl
+
+#endif // GGL_STRATEGY_AGNOSTIC_SIMPLIFY_DOUGLAS_PEUCKER_HPP
Added: sandbox/ggl/formal_review/boost/ggl/strategies/area.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/strategies/area.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,34 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGIES_AREA_HPP
+#define GGL_STRATEGIES_AREA_HPP
+
+#include <ggl/strategies/tags.hpp>
+
+
+namespace ggl
+{
+
+
+/*!
+    \brief Traits class binding an area strategy to a coordinate system
+    \ingroup area
+    \tparam Tag tag of coordinate system
+    \tparam PointOfSegment point-type
+*/
+template <typename Tag, typename PointOfSegment>
+struct strategy_area
+{
+    typedef strategy::not_implemented type;
+};
+
+
+} // namespace ggl
+
+#endif // GGL_STRATEGIES_AREA_HPP
Added: sandbox/ggl/formal_review/boost/ggl/strategies/area_result.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/strategies/area_result.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,45 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGIES_AREA_RESULT_HPP
+#define GGL_STRATEGIES_AREA_RESULT_HPP
+
+
+#include <ggl/core/cs.hpp>
+#include <ggl/core/coordinate_type.hpp>
+#include <ggl/strategies/area.hpp>
+#include <ggl/util/select_most_precise.hpp>
+
+
+namespace ggl
+{
+
+/*!
+    \brief Meta-function defining return type of area function
+    \ingroup area
+    \note The strategy defines the return-type (so this situation is different
+        from length, where distance is sqr/sqrt, but length always squared)
+
+ */
+template <typename Geometry>
+struct area_result
+{
+    typedef typename point_type<Geometry>::type point_type;
+    typedef typename strategy_area
+        <
+            typename cs_tag<point_type>::type,
+            point_type
+        >::type strategy_type;
+
+    typedef typename strategy_type::return_type type;
+};
+
+
+} // namespace ggl
+
+
+#endif // GGL_STRATEGIES_AREA_RESULT_HPP
Added: sandbox/ggl/formal_review/boost/ggl/strategies/cartesian/area_by_triangles.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/strategies/cartesian/area_by_triangles.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,110 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGIES_CARTESIAN_AREA_BY_TRIANGLES_HPP
+#define GGL_STRATEGIES_CARTESIAN_AREA_BY_TRIANGLES_HPP
+
+
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits.hpp>
+
+#include <ggl/geometries/point_xy.hpp>
+
+
+namespace ggl
+
+{
+namespace strategy { namespace area {
+
+/*!
+    \brief Strategy functor for area calculation on point_xy points
+    \details Calculates area using well-known triangulation algorithm
+    \tparam PointOfSegment point type of segments
+*/
+template
+<
+    typename PointOfSegment,
+    typename CalculationType = void
+>
+class by_triangles
+{
+public :
+    // If user specified a calculation type, use that type,
+    //   whatever it is and whatever the point-type is.
+    // Else, use the pointtype, but at least double
+    typedef typename
+        boost::mpl::if_c
+        <
+            boost::is_void<CalculationType>::type::value,
+            typename select_most_precise
+            <
+                typename coordinate_type<PointOfSegment>::type,
+                double
+            >::type,
+            CalculationType
+        >::type return_type;
+
+
+private :
+
+    class summation
+    {
+        friend class by_triangles;
+
+        return_type sum;
+    public :
+
+        inline summation() : sum(return_type())
+        {
+            // Strategy supports only 2D areas
+            assert_dimension<PointOfSegment, 2>();
+        }
+        inline return_type area() const
+        {
+            return_type result = sum;
+            result *= 0.5;
+            return result;
+        }
+    };
+
+public :
+    typedef summation state_type;
+    typedef PointOfSegment segment_point_type;
+
+    static inline void apply(PointOfSegment const& p1,
+                PointOfSegment const& p2,
+                summation& state)
+    {
+        // SUM += x2 * y1 - x1 * y2;
+        state.sum += get<0>(p2) * get<1>(p1) - get<0>(p1) * get<1>(p2);
+    }
+
+    static inline return_type result(summation const& state)
+    {
+        return state.area();
+    }
+
+};
+
+}} // namespace strategy::area
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+template <typename Point>
+struct strategy_area<cartesian_tag, Point>
+{
+    typedef strategy::area::by_triangles<Point> type;
+};
+
+#endif
+
+} // namespace ggl
+
+
+#endif // GGL_STRATEGIES_CARTESIAN_AREA_BY_TRIANGLES_HPP
Added: sandbox/ggl/formal_review/boost/ggl/strategies/cartesian/cart_intersect.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/strategies/cartesian/cart_intersect.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,354 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGIES_CARTESIAN_INTERSECTION_HPP
+#define GGL_STRATEGIES_CARTESIAN_INTERSECTION_HPP
+
+#include <algorithm>
+
+#include <ggl/core/exception.hpp>
+
+#include <ggl/geometries/concepts/point_concept.hpp>
+#include <ggl/geometries/concepts/segment_concept.hpp>
+
+#include <ggl/util/math.hpp>
+#include <ggl/util/select_coordinate_type.hpp>
+
+
+namespace ggl
+{
+
+
+class relate_cartesian_segments_exception : public ggl::exception
+{
+public:
+
+    relate_cartesian_segments_exception()  {}
+
+    virtual char const* what() const throw()
+    {
+        return "GGL: Internal error, unexpected case in relate_segment";
+    }
+};
+
+
+namespace strategy { namespace intersection {
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+template <typename S, size_t D>
+struct segment_interval
+{
+    template <typename T>
+    static inline void arrange(S const& s, T& s_1, T& s_2, bool& swapped)
+    {
+        s_1 = get<0, D>(s);
+        s_2 = get<1, D>(s);
+        if (s_1 > s_2)
+        {
+            std::swap(s_1, s_2);
+            swapped = true;
+        }
+    }
+};
+
+}
+#endif
+
+
+/*!
+    \see http://mathworld.wolfram.com/Line-LineIntersection.html
+ */
+template <typename F>
+struct relate_cartesian_segments
+{
+    typedef typename F::return_type RETURN_TYPE;
+    typedef typename F::segment_type1 S1;
+    typedef typename F::segment_type2 S2;
+
+    typedef typename point_type<S1>::type P;
+    BOOST_CONCEPT_ASSERT( (concept::Point<P>) );
+
+    BOOST_CONCEPT_ASSERT( (concept::ConstSegment<S1>) );
+    BOOST_CONCEPT_ASSERT( (concept::ConstSegment<S2>) );
+    typedef typename select_coordinate_type<S1, S2>::type T;
+
+    /// Relate segments a and b
+    static inline RETURN_TYPE relate(S1 const& a, S2 const& b)
+    {
+        T dx_a = get<1, 0>(a) - get<0, 0>(a); // distance in x-dir
+        T dx_b = get<1, 0>(b) - get<0, 0>(b);
+        T dy_a = get<1, 1>(a) - get<0, 1>(a); // distance in y-dir
+        T dy_b = get<1, 1>(b) - get<0, 1>(b);
+        return relate(a, b, dx_a, dy_a, dx_b, dy_b);
+    }
+
+
+    /// Relate segments a and b using precalculated differences. This can save two or four substractions in many cases
+    static inline RETURN_TYPE relate(S1 const& a, S2 const& b,
+            T const& dx_a, T const& dy_a, T const& dx_b, T const& dy_b)
+    {
+        T wx = get<0, 0>(a) - get<0, 0>(b);
+        T wy = get<0, 1>(a) - get<0, 1>(b);
+
+        // Calculate determinants - Cramers rule
+        T d = (dy_b * dx_a) - (dx_b * dy_a);
+        T da = (dx_b * wy) - (dy_b * wx);
+        T db = (dx_a * wy) - (dy_a * wx);
+
+        if(! math::equals(d, 0))
+        {
+            // Determinant d is nonzero. Rays do intersect. This is the normal case.
+            // ra/rb: ratio 0-1 where intersection divides A/B
+
+            // Maybe:
+            // The ra/rb calculation can probably also be avoided, only necessary to calculate the points themselves
+            // On segment: 0 <= r <= 1
+            //      where: r==0 and r==1 are special cases
+            // --> r=0 if and only if da==0 (d != 0) [this is also checked below]
+            // --> r=1 da==d
+            // --> da/d > 0 if da==positive and d==positive OR da==neg and d==neg
+            // --> da/d < 1 if (both positive) da < d or (negative) da > d, e.g. -2 > -4
+            // --> it would save a division but makes it complexer
+
+            double ra = double(da) / double(d);
+            double rb = double(db) / double(d);
+
+            return F::rays_intersect(ra >= 0 && ra <= 1 && rb >= 0 && rb <= 1, ra, rb,
+                dx_a, dy_a, dx_b, dy_b, wx, wy, a, b);
+        }
+
+        if(math::equals(da, 0) && math::equals(db, 0))
+        {
+            // Both da & db are zero. Segments are collinear. We'll find out how.
+            return relate_collinear(a, b, dx_a, dy_a, dx_b, dy_b);
+        }
+
+        // Segments are parallel (might still be opposite but this is probably never interesting)
+        return F::parallel();
+    }
+
+private :
+
+
+    /// Relate segments known collinear
+    static inline RETURN_TYPE relate_collinear(S1 const& a, S2 const& b,
+            T const& dx_a, T const& dy_a,
+            T const& dx_b, T const& dy_b)
+    {
+        // All ca. 200 lines are about collinear rays
+        // The intersections, if any, are always boundary points of the segments. No need to calculate anything.
+        // However we want to find out HOW they intersect, there are many cases.
+        // Most sources only provide the intersection (above) or that there is a collinearity (but not the points)
+        // or some spare sources give the intersection points (calculated) but not how they align.
+        // This source tries to give everything and still be efficient.
+        // It is therefore (and because of the extensive clarification comments) rather long...
+
+        // \see http://mpa.itc.it/radim/g50history/CMP/4.2.1-CERL-beta-libes/file475.txt
+        // \see http://docs.codehaus.org/display/GEOTDOC/Point+Set+Theory+and+the+DE-9IM+Matrix
+        // \see http://mathworld.wolfram.com/Line-LineIntersection.html
+
+        // Because of collinearity the case is now one-dimensional and can be checked using intervals
+        // We arrange either horizontally or vertically
+        // We get then two intervals:
+        // a_1-------------a_2 where a_1 < a_2
+        // b_1-------------b_2 where b_1 < b_2
+        // In all figures below a_1/a_2 denotes arranged intervals, a1-a2 or a2-a1 are still unarranged
+        T a_1, a_2, b_1, b_2;
+        bool a_swapped = false, b_swapped = false;
+        if (math::equals(dx_b, 0))
+        {
+            // Vertical -> Check y-direction
+            detail::segment_interval<S1, 1>::arrange(a, a_1, a_2, a_swapped);
+            detail::segment_interval<S1, 1>::arrange(b, b_1, b_2, b_swapped);
+        }
+        else
+        {
+            // Check x-direction
+            detail::segment_interval<S1, 0>::arrange(a, a_1, a_2, a_swapped);
+            detail::segment_interval<S1, 0>::arrange(b, b_1, b_2, b_swapped);
+        }
+
+        // First handle "disjoint", probably common case.
+        // 2 cases: a_1----------a_2    b_1-------b_2 or B left of A
+        if (a_2 < b_1 || a_1 > b_2)
+        {
+            return F::collinear_disjoint();
+        }
+
+        // Then handle "equal", in polygon neighbourhood comparisons also a common case
+
+        // Check if segments are equal...
+        bool a1_eq_b1 = math::equals(get<0, 0>(a), get<0, 0>(b))
+                    && math::equals(get<0, 1>(a), get<0, 1>(b));
+        bool a2_eq_b2 = math::equals(get<1, 0>(a), get<1, 0>(b))
+                    && math::equals(get<1, 1>(a), get<1, 1>(b));
+        if (a1_eq_b1 && a2_eq_b2)
+        {
+            return F::segment_equal(a, false);
+        }
+
+        // ... or opposite equal
+        bool a1_eq_b2 = math::equals(get<0, 0>(a), get<1, 0>(b))
+                    && math::equals(get<0, 1>(a), get<1, 1>(b));
+        bool a2_eq_b1 = math::equals(get<1, 0>(a), get<0, 0>(b))
+                    && math::equals(get<1, 1>(a), get<0, 1>(b));
+        if (a1_eq_b2 && a2_eq_b1)
+        {
+            return F::segment_equal(a, true);
+        }
+
+
+        // Degenerate cases: segments of single point, lying on other segment, non disjoint
+        if (math::equals(dx_a, 0) && math::equals(dy_a, 0))
+        {
+            return F::degenerate(a, true);
+        }
+        if (math::equals(dx_b, 0) && math::equals(dy_b, 0))
+        {
+            return F::degenerate(b, false);
+        }
+
+
+        // The rest below will return one or two intersections.
+        // The delegated class can decide which is the intersection point, or two, build the Intersection Matrix (IM)
+        // For IM it is important to know which relates to which. So this information is given,
+        // without performance penalties to intersection calculation
+
+        bool has_common_points = a1_eq_b1 || a1_eq_b2 || a2_eq_b1 || a2_eq_b2;
+
+
+        // "Touch" -> one intersection point -> one but not two common points
+        // -------->             A (or B)
+        //         <----------   B (or A)
+        //        a_2==b_1         (b_2==a_1 or a_2==b1)
+
+        // The check a_2/b_1 is necessary because it excludes cases like
+        // ------->
+        //     --->
+        // ... which are handled lateron
+
+        // Corresponds to 4 cases, of which the equal points are determined above
+        // 1: a1---->a2 b1--->b2   ("a" first)
+        // 2: a2<----a1 b2<---b1   ("b" first)
+        // 3: a1---->a2 b2<---b1   ("t": to)
+        // 4: a2<----a1 b1--->b2   ("f": from)
+        // Where the arranged forms have two forms:
+        //    a_1-----a_2/b_1-------b_2 or reverse (B left of A)
+        if (has_common_points && (math::equals(a_2, b_1) || math::equals(b_2, a_1)))
+        {
+            if (a2_eq_b1) return F::collinear_touch(get<1, 0>(a), get<1, 1>(a), false, 'A');
+            if (a2_eq_b2) return F::collinear_touch(get<1, 0>(a), get<1, 1>(a), true, 'T');
+            if (a1_eq_b2) return F::collinear_touch(get<0, 0>(a), get<0, 1>(a), false, 'B');
+            if (a1_eq_b1) return F::collinear_touch(get<0, 0>(a), get<0, 1>(a), true, 'F');
+        }
+
+
+        // "Touch/within" -> there are common points and also an intersection of interiors:
+        // Corresponds to many cases:
+        // Case 1: a1------->a2  Case 5:      a1-->a2  Case 9:  a1--->a2
+        //             b1--->b2          b1------->b2           b1---------b2
+        // Case 2: a2<-------a1
+        //             b1----b2  Et cetera
+        // Case 3: a1------->a2
+        //             b2<---b1
+        // Case 4: a2<-------a1
+        //             b2<---b1
+
+        // For case 1-4: a_1 < (b_1 or b_2) < a_2, two intersections are equal to segment B
+        // For case 5-8: b_1 < (a_1 or a_2) < b_2, two intersections are equal to segment A
+        if (has_common_points)
+        {
+            bool a_in_b =  (b_1 < a_1 && a_1 < b_2) || (b_1 < a_2 && a_2 < b_2);
+            if (a2_eq_b2) return F::collinear_interior_boundary_intersect(a_in_b ? a : b, a_in_b, false);
+            if (a1_eq_b2) return F::collinear_interior_boundary_intersect(a_in_b ? a : b, a_in_b, true);
+            if (a2_eq_b1) return F::collinear_interior_boundary_intersect(a_in_b ? a : b, a_in_b, true);
+            if (a1_eq_b1) return F::collinear_interior_boundary_intersect(a_in_b ? a : b, a_in_b, false);
+        }
+
+        bool opposite = a_swapped ^ b_swapped;
+
+
+        // "Inside", a completely within b or b completely within a
+        // 2 cases:
+        // case 1:
+        //        a_1---a_2        -> take A's points as intersection points
+        //   b_1------------b_2
+        // case 2:
+        //   a_1------------a_2
+        //       b_1---b_2         -> take B's points
+        if (a_1 > b_1 && a_2 < b_2)
+        {
+            // A within B
+            return F::collinear_a_in_b(a, opposite);
+        }
+        if (b_1 > a_1 && b_2 < a_2)
+        {
+            // B within A
+            return F::collinear_b_in_a(b, opposite);
+        }
+
+
+        // Now that all cases with equal,touch,inside,disjoint,degenerate are handled the only thing left is an overlap
+        // Case 1: a1--------->a2         a_1---------a_2
+        //                 b1----->b2             b_1------b_2
+        // Case 2: a2<---------a1         a_1---------a_2          a_swapped
+        //                 b1----->b2             b_1------b_2
+        // Case 3: a1--------->a2         a_1---------a_2
+        //                 b2<-----b1             b_1------b_2     b_swapped
+        // Case 4: a2<-------->a1         a_1---------a_2          a_swapped
+        //                 b2<-----b1             b_1------b_2     b_swapped
+
+        // Case 5:     a1--------->a2          a_1---------a_2
+        //         b1----->b2             b1--------b2
+        // Case 6:     a2<---------a1
+        //         b1----->b2
+        // Case 7:     a1--------->a2
+        //         b2<-----b1
+        // Case 8:     a2<-------->a1
+        //         b2<-----b1
+
+        if (a_1 < b_1 && b_1 < a_2)
+        {
+            // Case 4,2,3,1
+            return
+                  a_swapped && b_swapped   ? F::collinear_overlaps(get<0, 0>(a), get<0, 1>(a), get<1, 0>(b), get<1, 1>(b), opposite)
+                : a_swapped                ? F::collinear_overlaps(get<0, 0>(a), get<0, 1>(a), get<0, 0>(b), get<0, 1>(b), opposite)
+                : b_swapped                ? F::collinear_overlaps(get<1, 0>(a), get<1, 1>(a), get<1, 0>(b), get<1, 1>(b), opposite)
+                :                            F::collinear_overlaps(get<1, 0>(a), get<1, 1>(a), get<0, 0>(b), get<0, 1>(b), opposite)
+                ;
+        }
+        if (b_1 < a_1 && a_1 < b_2)
+        {
+            // Case 8, 6, 7, 5
+            return
+                  a_swapped && b_swapped   ? F::collinear_overlaps(get<1, 0>(a), get<1, 1>(a), get<0, 0>(b), get<0, 1>(b), opposite)
+                : a_swapped                ? F::collinear_overlaps(get<1, 0>(a), get<1, 1>(a), get<1, 0>(b), get<1, 1>(b), opposite)
+                : b_swapped                ? F::collinear_overlaps(get<0, 0>(a), get<0, 1>(a), get<0, 0>(b), get<0, 1>(b), opposite)
+                :                            F::collinear_overlaps(get<0, 0>(a), get<0, 1>(a), get<1, 0>(b), get<1, 1>(b), opposite)
+                ;
+        }
+
+        // Nothing should goes through. If any we have made an error
+        // TODO: proper exception
+        throw relate_cartesian_segments_exception();
+    }
+};
+
+
+}} // namespace strategy::intersection
+
+
+
+} // namespace ggl
+
+
+#endif // GGL_STRATEGIES_CARTESIAN_INTERSECTION_HPP
Added: sandbox/ggl/formal_review/boost/ggl/strategies/cartesian/centroid_bashein_detmer.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/strategies/cartesian/centroid_bashein_detmer.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,238 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGIES_CARTESIAN_CENTROID_BASHEIN_DETMER_HPP
+#define GGL_STRATEGIES_CARTESIAN_CENTROID_BASHEIN_DETMER_HPP
+
+
+#include <boost/mpl/if.hpp>
+#include <boost/numeric/conversion/cast.hpp>
+#include <boost/type_traits.hpp>
+
+#include <ggl/core/coordinate_type.hpp>
+#include <ggl/core/point_type.hpp>
+#include <ggl/strategies/centroid.hpp>
+#include <ggl/util/select_coordinate_type.hpp>
+#include <ggl/util/copy.hpp>
+
+
+namespace ggl
+{
+
+// Note: when calling the namespace "centroid", it sometimes,
+// somehow, in gcc, gives compilation problems (confusion with function centroid).
+
+namespace strategy { namespace centroid_ {
+
+
+
+/*!
+    \brief Centroid calculation using algorith Bashein / Detmer
+    \details Calculates centroid using triangulation method published by
+        Bashein / Detmer
+    \tparam Point point type of centroid to calculate
+    \tparam PointOfSegment point type of segments, defaults to Point
+    \par Concepts for Point and PointOfSegment:
+    - specialized point_traits class
+    \author Adapted from  "Centroid of a Polygon" by
+        Gerard Bashein and Paul R. Detmer<em>,
+    in "Graphics Gems IV", Academic Press, 1994</em>
+    \par Research notes
+    The algorithm gives the same results as Oracle and PostGIS but
+        differs from MySQL
+    (tried 5.0.21 / 5.0.45 / 5.0.51a / 5.1.23).
+
+    Without holes:
+    - this:       POINT(4.06923363095238 1.65055803571429)
+    - geolib:     POINT(4.07254 1.66819)
+    - MySQL:      POINT(3.6636363636364  1.6272727272727)'
+    - PostGIS:    POINT(4.06923363095238 1.65055803571429)
+    - Oracle:           4.06923363095238 1.65055803571429
+    - SQL Server: POINT(4.06923362245959 1.65055804168294)
+
+    Statements:
+    - \b MySQL/PostGIS: select AsText(Centroid(GeomFromText(
+        'POLYGON((2 1.3,2.4 1.7,2.8 1.8,3.4 1.2,3.7 1.6,3.4 2,4.1 3,5.3 2.6
+            ,5.4 1.2,4.9 0.8,2.9 0.7,2 1.3))')))
+    - \b Oracle: select sdo_geom.sdo_centroid(sdo_geometry(2003, null, null,
+            sdo_elem_info_array(1, 1003, 1), sdo_ordinate_array(
+                2,1.3,2.4,1.7,2.8,1.8,3.4,1.2,3.7,1.6,3.4,2,4.1,3,5.3,2.6
+                ,5.4,1.2,4.9,0.8,2.9,0.7,2,1.3))
+            , mdsys.sdo_dim_array(mdsys.sdo_dim_element('x',0,10,.00000005)
+            ,mdsys.sdo_dim_element('y',0,10,.00000005)))
+            from dual
+    - \b SQL Server 2008: select geometry::STGeomFromText(
+        'POLYGON((2 1.3,2.4 1.7,2.8 1.8,3.4 1.2,3.7 1.6,3.4 2,4.1 3,5.3 2.6
+            ,5.4 1.2,4.9 0.8,2.9 0.7,2 1.3))',0)
+                    .STCentroid()
+                    .STAsText()
+
+    With holes:
+    - this:       POINT(4.04663 1.6349)
+    - geolib:     POINT(4.04675 1.65735)
+    - MySQL:      POINT(3.6090580503834 1.607573932092)
+    - PostGIS:    POINT(4.0466265060241 1.63489959839357)
+    - Oracle:           4.0466265060241 1.63489959839357
+    - SQL Server: POINT(4.0466264962959677 1.6348996057331333)
+
+    Statements:
+    - \b MySQL/PostGIS: select AsText(Centroid(GeomFromText(
+        'POLYGON((2 1.3,2.4 1.7,2.8 1.8,3.4 1.2
+            ,3.7 1.6,3.4 2,4.1 3,5.3 2.6,5.4 1.2,4.9 0.8,2.9 0.7,2 1.3)
+            ,(4 2,4.2 1.4,4.8 1.9,4.4 2.2,4 2))')));
+    - \b Oracle: select sdo_geom.sdo_centroid(sdo_geometry(2003, null, null
+            , sdo_elem_info_array(1, 1003, 1, 25, 2003, 1)
+            , sdo_ordinate_array(2,1.3,2.4,1.7,2.8,1.8,3.4,1.2,3.7,1.6,3.4,
+            2,4.1,3,5.3,2.6,5.4,1.2,4.9,0.8,2.9,0.7,2,1.3,4,2, 4.2,1.4,
+            4.8,1.9, 4.4,2.2, 4,2))
+            , mdsys.sdo_dim_array(mdsys.sdo_dim_element('x',0,10,.00000005)
+            ,mdsys.sdo_dim_element('y',0,10,.00000005)))
+            from dual
+ */
+template
+<
+    typename Point,
+    typename PointOfSegment = Point,
+    typename CalculationType = void
+>
+class bashein_detmer
+{
+private :
+    // If user specified a calculation type, use that type,
+    //   whatever it is and whatever the point-type(s) are.
+    // Else, use the most appropriate coordinate type
+    //    of the two points, but at least double
+    typedef typename
+        boost::mpl::if_c
+        <
+            boost::is_void<CalculationType>::type::value,
+            typename select_most_precise
+            <
+                typename select_coordinate_type
+                    <
+                        Point,
+                        PointOfSegment
+                    >::type,
+                double
+            >::type,
+            CalculationType
+        >::type calculation_type;
+
+    /*! subclass to keep state */
+    class sums
+    {
+        friend class bashein_detmer;
+        int count;
+        calculation_type sum_a2;
+        calculation_type sum_x;
+        calculation_type sum_y;
+
+    public :
+        inline sums()
+            : count(0)
+            , sum_a2(calculation_type())
+            , sum_x(calculation_type())
+            , sum_y(calculation_type())
+        {
+            typedef calculation_type ct;
+            //std::cout << "-> calctype: " << typeid(ct).name()
+            //    << " size: " << sizeof(ct)
+            //    << " init: " << sum_a2
+            //    << std::endl;
+        }
+    };
+
+public :
+    typedef sums state_type;
+    typedef Point point_type;
+    typedef PointOfSegment segment_point_type;
+
+    static inline void apply(PointOfSegment const& p1,
+            PointOfSegment const& p2, sums& state)
+    {
+        /* Algorithm:
+        For each segment:
+        begin
+            ai = x1 * y2 - x2 * y1;
+            sum_a2 += ai;
+            sum_x += ai * (x1 + x2);
+            sum_y += ai * (y1 + y2);
+        end
+        return POINT(sum_x / (3 * sum_a2), sum_y / (3 * sum_a2) )
+        */
+
+        // Get coordinates and promote them to calculation_type
+        calculation_type const x1 = boost::numeric_cast<calculation_type>(get<0>(p1));
+        calculation_type const y1 = boost::numeric_cast<calculation_type>(get<1>(p1));
+        calculation_type const x2 = boost::numeric_cast<calculation_type>(get<0>(p2));
+        calculation_type const y2 = boost::numeric_cast<calculation_type>(get<1>(p2));
+        calculation_type const ai = x1 * y2 - x2 * y1;
+        state.count++;
+        state.sum_a2 += ai;
+        state.sum_x += ai * (x1 + x2);
+        state.sum_y += ai * (y1 + y2);
+    }
+
+    static inline bool result(sums const& state, Point& centroid)
+    {
+        if (state.count > 0 && state.sum_a2 != 0)
+        {
+            calculation_type const v3 = 3;
+            calculation_type const a3 = v3 * state.sum_a2;
+
+            typedef typename ggl::coordinate_type
+                <
+                    Point
+                >::type coordinate_type;
+
+            set<0>(centroid,
+                boost::numeric_cast<coordinate_type>(state.sum_x / a3));
+            set<1>(centroid,
+                boost::numeric_cast<coordinate_type>(state.sum_y / a3));
+            return true;
+        }
+
+        return false;
+    }
+
+};
+
+
+}} // namespace strategy::centroid
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+// Register this strategy for rings and polygons, in two dimensions
+template <typename Point, typename Geometry>
+struct strategy_centroid<cartesian_tag, ring_tag, 2, Point, Geometry>
+{
+    typedef strategy::centroid_::bashein_detmer
+        <
+            Point,
+            typename point_type<Geometry>::type
+        > type;
+};
+
+template <typename Point, typename Geometry>
+struct strategy_centroid<cartesian_tag, polygon_tag, 2, Point, Geometry>
+{
+    typedef strategy::centroid_::bashein_detmer
+        <
+            Point,
+            typename point_type<Geometry>::type
+        > type;
+};
+
+#endif
+
+
+} // namespace ggl
+
+
+#endif // GGL_STRATEGIES_CARTESIAN_CENTROID_BASHEIN_DETMER_HPP
Added: sandbox/ggl/formal_review/boost/ggl/strategies/cartesian/distance_projected_point.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/strategies/cartesian/distance_projected_point.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,168 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGIES_CARTESIAN_DISTANCE_PROJECTED_POINT_HPP
+#define GGL_STRATEGIES_CARTESIAN_DISTANCE_PROJECTED_POINT_HPP
+
+
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/point_type.hpp>
+
+#include <ggl/arithmetic/arithmetic.hpp>
+#include <ggl/arithmetic/dot_product.hpp>
+
+#include <ggl/strategies/tags.hpp>
+#include <ggl/strategies/distance.hpp>
+#include <ggl/strategies/distance_result.hpp>
+#include <ggl/strategies/cartesian/distance_pythagoras.hpp>
+
+#include <ggl/util/select_coordinate_type.hpp>
+#include <ggl/util/copy.hpp>
+
+
+// Helper geometry
+#include <ggl/geometries/segment.hpp>
+
+namespace ggl {
+
+namespace strategy { namespace distance {
+
+
+
+/*!
+    \brief Strategy for distance point to segment
+    \ingroup distance
+    \details Calculates distance using projected-point method, and (optionally) Pythagoras
+    \author Adapted from: http://geometryalgorithms.com/Archive/algorithm_0102/algorithm_0102.htm
+    \tparam P point type
+    \tparam PointOfSegment segment type
+    \tparam Strategy strategy, optional, defaults to pythagoras
+    \par Concepts for Strategy:
+    - cartesian_distance operator(Point,Point)
+*/
+template
+<
+    typename Point,
+    typename PointOfSegment,
+    typename Strategy = pythagoras
+        <
+            Point,
+            typename point_type<PointOfSegment>::type
+        >
+>
+struct xy_point_segment
+{
+    typedef Point point_type;
+    typedef PointOfSegment segment_point_type;
+    typedef typename select_coordinate_type
+        <
+            Point,
+            PointOfSegment
+        >::type coordinate_type;
+    typedef cartesian_distance<coordinate_type> return_type;
+
+    typedef Strategy point_strategy_type;
+
+
+    inline return_type apply(Point const& p,
+                    PointOfSegment const& p1, PointOfSegment const& p2) const
+    {
+        assert_dimension_equal<Point, PointOfSegment>();
+
+        /* Algorithm
+        POINT v(x2 - x1, y2 - y1);
+        POINT w(px - x1, py - y1);
+        c1 = w . v
+        c2 = v . v
+        b = c1 / c2
+        RETURN POINT(x1 + b * vx, y1 + b * vy);
+        */
+
+
+        // Take here the first point type. It should have a default constructor.
+        // That is not required for the second point type.
+        Point v, w;
+
+        copy_coordinates(p2, v);
+        copy_coordinates(p, w);
+        subtract_point(v, p1);
+        subtract_point(w, p1);
+
+        Strategy strategy;
+
+        coordinate_type c1 = dot_product(w, v);
+        if (c1 <= 0)
+        {
+            return strategy.apply(p, p1);
+        }
+        coordinate_type c2 = dot_product(v, v);
+        if (c2 <= c1)
+        {
+            return strategy.apply(p, p2);
+        }
+
+        // Even in case of char's, we have to turn to a point<double/float>
+        // because of the division.
+        // TODO
+        coordinate_type b = c1 / c2;
+
+        // Note that distances with integer coordinates do NOT work because
+        // - the project point is integer
+        // - if we solve that, the used distance_strategy cannot handle double points
+        PointOfSegment projected;
+        copy_coordinates(p1, projected);
+        multiply_value(v, b);
+        add_point(projected, v);
+
+        return strategy.apply(p, projected);
+
+    }
+
+};
+
+}} // namespace strategy::distance
+
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+template <typename Point, typename PointOfSegment>
+struct strategy_distance_segment<cartesian_tag, cartesian_tag, Point, PointOfSegment>
+{
+    typedef typename point_type<PointOfSegment>::type segment_point_type;
+
+    typedef strategy::distance::xy_point_segment
+    <
+        Point,
+        PointOfSegment,
+        typename strategy_distance
+        <
+            cartesian_tag, cartesian_tag, Point, segment_point_type
+        >::type
+    > type;
+};
+#endif
+
+
+template <typename Point, typename PointOfSegment, typename PPStrategy>
+struct strategy_tag<strategy::distance::xy_point_segment<Point, PointOfSegment, PPStrategy> >
+{
+    typedef strategy_tag_distance_point_segment type;
+};
+
+
+
+} // namespace ggl
+
+
+#endif // GGL_STRATEGIES_CARTESIAN_DISTANCE_PROJECTED_POINT_HPP
Added: sandbox/ggl/formal_review/boost/ggl/strategies/cartesian/distance_pythagoras.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/strategies/cartesian/distance_pythagoras.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,130 @@
+// Generic Geometry Library
+//
+// Copyright Bruno Lalande 2008, 2009
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_HPP
+#define GGL_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_HPP
+
+
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits.hpp>
+
+#include <ggl/core/access.hpp>
+
+#include <ggl/strategies/distance.hpp>
+#include <ggl/strategies/distance_result.hpp>
+
+#include <ggl/util/select_calculation_type.hpp>
+#include <ggl/util/copy.hpp>
+
+
+
+namespace ggl {
+
+namespace strategy { namespace distance {
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+template <typename Point1, typename Point2, size_t I, typename T>
+struct compute_pythagoras
+{
+    static inline T apply(Point1 const& p1, Point2 const& p2)
+    {
+        T const c1 = boost::numeric_cast<T>(get<I-1>(p2));
+        T const c2 = boost::numeric_cast<T>(get<I-1>(p1));
+        T const d = c1 - c2;
+        return d * d + compute_pythagoras<Point1, Point2, I-1, T>::apply(p1, p2);
+    }
+};
+
+template <typename Point1, typename Point2, typename T>
+struct compute_pythagoras<Point1, Point2, 0, T>
+{
+    static inline T apply(Point1 const&, Point2 const&)
+    {
+        return boost::numeric_cast<T>(0);
+    }
+};
+
+}
+#endif // DOXYGEN_NO_DETAIL
+
+/*!
+    \brief Strategy for distance point to point: pythagoras
+    \ingroup distance
+    \tparam Point1 first point type
+    \tparam Point2 optional, second point type, defaults to first point type
+    \par Concepts for Point1 and Point2:
+    - specialized point_traits class
+*/
+template
+<
+    typename Point1,
+    typename Point2 = Point1,
+    typename CalculationType = void
+>
+struct pythagoras
+{
+    typedef typename select_calculation_type
+        <
+            Point1,
+            Point2,
+            CalculationType
+        >::type calculation_type;
+
+    typedef Point1 first_point_type;
+    typedef Point2 second_point_type;
+    typedef cartesian_distance<calculation_type> return_type;
+
+    inline return_type apply(Point1 const& p1, Point2 const& p2) const
+    {
+        BOOST_CONCEPT_ASSERT( (concept::ConstPoint<Point1>) );
+        BOOST_CONCEPT_ASSERT( (concept::ConstPoint<Point2>) );
+
+        // Calculate distance using Pythagoras
+        // (Leave comment above for Doxygen)
+
+        assert_dimension_equal<Point1, Point2>();
+
+        return return_type(detail::compute_pythagoras
+            <
+                Point1, Point2,
+                dimension<Point1>::value,
+                calculation_type
+            >::apply(p1, p2));
+    }
+};
+
+
+}} // namespace strategy::distance
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+template <typename Point1, typename Point2>
+struct strategy_distance<cartesian_tag, cartesian_tag, Point1, Point2>
+{
+    typedef strategy::distance::pythagoras<Point1, Point2> type;
+};
+
+
+#endif
+
+
+template <typename Point1, typename Point2>
+struct strategy_tag<strategy::distance::pythagoras<Point1, Point2> >
+{
+    typedef strategy_tag_distance_point_point type;
+};
+
+
+
+} // namespace ggl
+
+
+#endif // GGL_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_HPP
Added: sandbox/ggl/formal_review/boost/ggl/strategies/cartesian/point_in_poly_crossings_multiply.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/strategies/cartesian/point_in_poly_crossings_multiply.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,109 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 2009, Geodan, Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGIES_CARTESIAN_POINT_IN_POLY_CROSSINGS_MULTIPLY_HPP
+#define GGL_STRATEGIES_CARTESIAN_POINT_IN_POLY_CROSSINGS_MULTIPLY_HPP
+
+
+#include <ggl/core/coordinate_type.hpp>
+#include <ggl/util/select_calculation_type.hpp>
+
+
+namespace ggl
+
+{
+namespace strategy { namespace within {
+
+/*!
+    \brief Within detection using cross counting,
+    \see http://tog.acm.org/resources/GraphicsGems/gemsiv/ptpoly_haines/ptinpoly.c
+    \note Does NOT work correctly for point ON border
+ */
+
+template
+<
+    typename Point,
+    typename PointOfSegment = Point,
+    typename CalculationType = void
+>
+class crossings_multiply
+{
+    typedef typename select_calculation_type
+        <
+            Point,
+            PointOfSegment,
+            CalculationType
+        >::type calculation_type;
+
+    class flags
+    {
+        bool inside_flag;
+        bool first;
+        bool yflag0;
+
+    public :
+
+        friend class crossings_multiply;
+
+        inline flags()
+            : inside_flag(false)
+            , first(true)
+            , yflag0(false)
+        {}
+    };
+
+public :
+
+    typedef Point point_type;
+    typedef PointOfSegment segment_point_type;
+    typedef flags state_type;
+
+    static inline bool apply(Point const& point,
+            PointOfSegment const& seg1, PointOfSegment const& seg2,
+            flags& state)
+    {
+        calculation_type const tx = get<0>(point);
+        calculation_type const ty = get<1>(point);
+        calculation_type const x0 = get<0>(seg1);
+        calculation_type const y0 = get<1>(seg1);
+        calculation_type const x1 = get<0>(seg2);
+        calculation_type const y1 = get<1>(seg2);
+
+        if (state.first)
+        {
+            state.first = false;
+            state.yflag0 = y0 >= ty;
+        }
+
+
+        bool yflag1 = y1 >= ty;
+        if (state.yflag0 != yflag1)
+        {
+            if ( ((y1-ty) * (x0-x1) >= (x1-tx) * (y0-y1)) == yflag1 )
+            {
+                state.inside_flag = ! state.inside_flag;
+            }
+        }
+        state.yflag0 = yflag1;
+        return true;
+    }
+
+    static inline bool result(flags const& state)
+    {
+        return state.inside_flag;
+    }
+};
+
+
+
+}} // namespace strategy::within
+
+
+} // namespace ggl
+
+
+#endif // GGL_STRATEGIES_CARTESIAN_POINT_IN_POLY_CROSSINGS_MULTIPLY_HPP
Added: sandbox/ggl/formal_review/boost/ggl/strategies/cartesian/point_in_poly_franklin.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/strategies/cartesian/point_in_poly_franklin.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,104 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGIES_CARTESIAN_POINT_IN_POLY_FRANKLIN_HPP
+#define GGL_STRATEGIES_CARTESIAN_POINT_IN_POLY_FRANKLIN_HPP
+
+
+#include <ggl/core/coordinate_type.hpp>
+#include <ggl/util/select_calculation_type.hpp>
+
+
+namespace ggl
+
+{
+namespace strategy { namespace within {
+
+/*!
+    \brief Within detection using cross counting
+
+    \author adapted from Randolph Franklin algorithm
+    \author Barend and Maarten, 1995
+    \author Revised for templatized library, Barend Gehrels, 2007
+    \return true if point is in ring, works for closed rings in both directions
+    \note Does NOT work correctly for point ON border
+ */
+
+template
+<
+    typename Point,
+    typename PointOfSegment = Point,
+    typename CalculationType = void
+>
+class franklin
+{
+    typedef typename select_calculation_type
+        <
+            Point,
+            PointOfSegment,
+            CalculationType
+        >::type calculation_type;
+
+        /*! subclass to keep state */
+        class crossings
+        {
+            bool crosses;
+
+        public :
+
+            friend class franklin;
+            inline crossings()
+                : crosses(false)
+            {}
+        };
+
+public :
+
+    typedef Point point_type;
+    typedef PointOfSegment segment_point_type;
+    typedef crossings state_type;
+
+    static inline bool apply(Point const& point,
+            PointOfSegment const& seg1, PointOfSegment const& seg2,
+            crossings& state)
+    {
+        calculation_type const& px = get<0>(point);
+        calculation_type const& py = get<1>(point);
+        calculation_type const& x1 = get<0>(seg1);
+        calculation_type const& y1 = get<1>(seg1);
+        calculation_type const& x2 = get<0>(seg2);
+        calculation_type const& y2 = get<1>(seg2);
+
+        if (
+            ( (y2 <= py && py < y1) || (y1 <= py && py < y2) )
+            && (px < (x1 - x2) * (py - y2) / (y1 - y2) + x2)
+            )
+        {
+            state.crosses = ! state.crosses;
+        }
+        return true;
+    }
+
+    static inline bool result(crossings const& state)
+    {
+        return state.crosses;
+    }
+};
+
+
+
+}} // namespace strategy::within
+
+
+
+
+
+} // namespace ggl
+
+
+#endif // GGL_STRATEGIES_CARTESIAN_POINT_IN_POLY_FRANKLIN_HPP
Added: sandbox/ggl/formal_review/boost/ggl/strategies/cartesian/side_by_triangle.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/strategies/cartesian/side_by_triangle.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,86 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGIES_CARTESIAN_SIDE_BY_TRIANGLE_HPP
+#define GGL_STRATEGIES_CARTESIAN_SIDE_BY_TRIANGLE_HPP
+
+
+
+#include <ggl/geometries/segment.hpp>
+
+#include <ggl/util/select_coordinate_type.hpp>
+
+
+
+namespace ggl
+{
+namespace strategy
+{
+    namespace side
+    {
+
+        // Check at which side of a segment a point lies:
+        // left of segment (> 0), right of segment (< 0), on segment (0)
+        // In fact this is twice the area of a triangle
+        struct side_by_triangle
+        {
+
+            // Template member functions, because it is not always trivial
+            // or convenient to explicitly mention the typenames in the
+            // strategy-struct itself.
+
+            // Types can be all three different.
+
+            template <typename P1, typename P2, typename P>
+            static inline int apply(P1 const& p1, P2 const& p2, P const& p)
+            {
+                typedef typename select_most_precise
+                    <
+                        typename select_most_precise
+                            <
+                                typename coordinate_type<P1>::type,
+                                typename coordinate_type<P2>::type
+                            >::type,
+                        typename coordinate_type<P>::type
+                    >::type coordinate_type;
+
+                coordinate_type const x = get<0>(p);
+                coordinate_type const y = get<1>(p);
+
+                coordinate_type const sx1 = get<0>(p1);
+                coordinate_type const sy1 = get<1>(p1);
+                coordinate_type const sx2 = get<0>(p2);
+                coordinate_type const sy2 = get<1>(p2);
+
+                coordinate_type const dx = sx2 - sx1;
+                coordinate_type const dy = sy2 - sy1;
+                coordinate_type const dpx = x - sx1;
+                coordinate_type const dpy = y - sy1;
+
+                coordinate_type s = dx * dpy - dy * dpx;
+
+                return s > 0 ? 1 : s < 0 ? -1 : 0;
+            }
+        };
+
+    } // namespace side
+} // namespace strategy
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+template <>
+struct strategy_side<cartesian_tag>
+{
+    typedef strategy::side::side_by_triangle type;
+};
+#endif
+
+} // namespace ggl
+
+
+#endif // GGL_STRATEGIES_CARTESIAN_SIDE_BY_TRIANGLE_HPP
Added: sandbox/ggl/formal_review/boost/ggl/strategies/centroid.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/strategies/centroid.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,45 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGIES_CENTROID_HPP
+#define GGL_STRATEGIES_CENTROID_HPP
+
+
+#include <ggl/strategies/tags.hpp>
+
+
+namespace ggl
+{
+
+
+/*!
+    \brief Traits class binding a centroid calculation strategy to a coordinate system
+    \ingroup centroid
+    \tparam CsTag tag of coordinate system, for specialization
+    \tparam GeometryTag tag of geometry, for specialization
+    \tparam Dimension dimension of geometry, for specialization
+    \tparam Point point-type
+    \tparam Geometry
+*/
+template
+<
+    typename CsTag,
+    typename GeometryTag,
+    std::size_t Dimension,
+    typename Point,
+    typename Geometry
+>
+struct strategy_centroid
+{
+    typedef strategy::not_implemented type;
+};
+
+
+} // namespace ggl
+
+#endif // GGL_STRATEGIES_CENTROID_HPP
Added: sandbox/ggl/formal_review/boost/ggl/strategies/compare.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/strategies/compare.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,171 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan,. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef GGL_STRATEGIES_COMPARE_HPP
+#define GGL_STRATEGIES_COMPARE_HPP
+
+#include <cstddef>
+#include <functional>
+
+#include <boost/mpl/if.hpp>
+
+#include <ggl/core/cs.hpp>
+#include <ggl/core/coordinate_type.hpp>
+
+
+#include <ggl/strategies/tags.hpp>
+
+
+namespace ggl
+{
+
+
+
+/*!
+    \brief Traits class binding a comparing strategy to a coordinate system
+    \ingroup util
+    \tparam Tag tag of coordinate system of point-type
+    \tparam Direction direction to compare on: 1 for less (-> ascending order)
+        and -1 for greater (-> descending order)
+    \tparam Point point-type
+    \tparam CoordinateSystem coordinate sytem of point
+    \tparam Dimension: the dimension to compare on
+*/
+template
+<
+    typename Tag,
+    int Direction,
+    typename Point,
+    typename CoordinateSystem,
+    std::size_t Dimension
+>
+struct strategy_compare
+{
+    typedef strategy::not_implemented type;
+};
+
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+// For compare we add defaults specializations,
+// because they defaultly redirect to std::less / greater / equal_to
+template
+<
+    typename Tag,
+    typename Point,
+    typename CoordinateSystem,
+    std::size_t Dimension
+>
+struct strategy_compare<Tag, 1, Point, CoordinateSystem, Dimension>
+{
+    typedef std::less<typename coordinate_type<Point>::type> type;
+};
+
+
+template
+<
+    typename Tag,
+    typename Point,
+    typename CoordinateSystem,
+    std::size_t Dimension
+>
+struct strategy_compare<Tag, -1, Point, CoordinateSystem, Dimension>
+{
+    typedef std::greater<typename coordinate_type<Point>::type> type;
+};
+
+
+template
+<
+    typename Tag,
+    typename Point,
+    typename CoordinateSystem,
+    std::size_t Dimension
+>
+struct strategy_compare<Tag, 0, Point, CoordinateSystem, Dimension>
+{
+    typedef std::equal_to<typename coordinate_type<Point>::type> type;
+};
+
+
+
+#endif
+
+
+
+namespace strategy { namespace compare {
+
+
+
+/*!
+    \brief Default strategy, indicates the default strategy for comparisons
+    \details The default strategy for comparisons defer in most cases
+        to std::less (for ascending) and std::greater (for descending).
+        However, if a spherical coordinate system is used, and comparison
+        is done on longitude, it will take another strategy handling circular
+*/
+struct default_strategy {};
+
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail {
+
+template <typename Type>
+struct is_default : boost::false_type
+{};
+
+
+template <>
+struct is_default<default_strategy> : boost::true_type
+{};
+
+
+/*!
+    \brief Meta-function to select strategy
+    \details If "default_strategy" is specified, it will take the
+        traits-registered class for the specified coordinate system.
+        If another strategy is explicitly specified, it takes that one.
+*/
+template
+<
+    typename Strategy,
+    int Direction,
+    typename Point,
+    std::size_t Dimension
+>
+struct select_strategy
+{
+    typedef typename
+        boost::mpl::if_
+        <
+            is_default<Strategy>,
+            typename strategy_compare
+            <
+                typename cs_tag<Point>::type,
+                Direction,
+                Point,
+                typename coordinate_system<Point>::type,
+                Dimension
+            >::type,
+            Strategy
+        >::type type;
+};
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+}} // namespace strategy::compare
+
+
+} // namespace ggl
+
+#endif // GGL_STRATEGIES_COMPARE_HPP
Added: sandbox/ggl/formal_review/boost/ggl/strategies/concepts/area_concept.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/strategies/concepts/area_concept.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,69 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGIES_CONCEPTS_AREA_CONCEPT_HPP
+#define GGL_STRATEGIES_CONCEPTS_AREA_CONCEPT_HPP
+
+
+
+#include <boost/concept_check.hpp>
+
+
+namespace ggl { namespace concept {
+
+
+/*!
+    \brief Checks strategy for area
+    \ingroup area
+*/
+template <typename Strategy>
+class AreaStrategy
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+
+    // 1) must define state_type,
+    typedef typename Strategy::state_type state_type;
+
+    // 2) must define return_type,
+    typedef typename Strategy::return_type return_type;
+
+    // 3) must define point_type, of polygon (segments)
+    typedef typename Strategy::segment_point_type spoint_type;
+
+    struct check_methods
+    {
+        static void apply()
+        {
+            Strategy const* str;
+            state_type *st;
+
+            // 4) must implement a method apply with the following signature
+            spoint_type const* sp;
+            str->apply(*sp, *sp, *st);
+
+            // 5) must implement a static method result with the following signature
+            return_type r = str->result(*st);
+
+            boost::ignore_unused_variable_warning(r);
+            boost::ignore_unused_variable_warning(str);
+        }
+    };
+
+public :
+    BOOST_CONCEPT_USAGE(AreaStrategy)
+    {
+        check_methods::apply();
+    }
+
+#endif
+};
+
+
+
+}} // namespace ggl::concept
+
+#endif // GGL_STRATEGIES_CONCEPTS_AREA_CONCEPT_HPP
Added: sandbox/ggl/formal_review/boost/ggl/strategies/concepts/centroid_concept.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/strategies/concepts/centroid_concept.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,71 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGIES_CONCEPTS_CENTROID_CONCEPT_HPP
+#define GGL_STRATEGIES_CONCEPTS_CENTROID_CONCEPT_HPP
+
+
+
+#include <boost/concept_check.hpp>
+
+
+namespace ggl { namespace concept {
+
+
+/*!
+    \brief Checks strategy for centroid
+    \ingroup centroid
+*/
+template <typename Strategy>
+class CentroidStrategy
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+
+    // 1) must define state_type,
+    typedef typename Strategy::state_type state_type;
+
+    // 2) must define point_type,
+    typedef typename Strategy::point_type point_type;
+
+    // 3) must define point_type, of polygon (segments)
+    typedef typename Strategy::segment_point_type spoint_type;
+
+    struct check_methods
+    {
+        static void apply()
+        {
+            Strategy *str;
+            state_type *st;
+
+            // 4) must implement a static method apply,
+            // getting two segment-points
+            spoint_type const* sp;
+            str->apply(*sp, *sp, *st);
+
+            // 5) must implement a static method result
+            //  getting the centroid
+            point_type *c;
+            bool r = str->result(*st, *c);
+
+            boost::ignore_unused_variable_warning(str);
+            boost::ignore_unused_variable_warning(r);
+        }
+    };
+
+public :
+    BOOST_CONCEPT_USAGE(CentroidStrategy)
+    {
+        check_methods::apply();
+    }
+#endif
+};
+
+
+
+}} // namespace ggl::concept
+
+#endif // GGL_STRATEGIES_CONCEPTS_CENTROID_CONCEPT_HPP
Added: sandbox/ggl/formal_review/boost/ggl/strategies/concepts/convex_hull_concept.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/strategies/concepts/convex_hull_concept.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,68 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGIES_CONCEPTS_CONVEX_HULL_CONCEPT_HPP
+#define GGL_STRATEGIES_CONCEPTS_CONVEX_HULL_CONCEPT_HPP
+
+
+#include <vector>
+
+#include <boost/concept_check.hpp>
+
+
+namespace ggl { namespace concept {
+
+
+/*!
+    \brief Checks strategy for convex_hull
+    \ingroup convex_hull
+*/
+template <typename Strategy>
+class ConvexHullStrategy
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+
+    // 1) must define state_type
+    typedef typename Strategy::state_type state_type;
+
+    // 2) must define point_type
+    typedef typename Strategy::point_type point_type;
+
+    // 3) must define geometry_type
+    typedef typename Strategy::geometry_type geometry_type;
+
+    struct check_methods
+    {
+        static void apply()
+        {
+            Strategy const* str;
+
+            state_type* st;
+            geometry_type* sp;
+            std::vector<point_type> *v;
+
+            // 4) must implement a method apply, iterating over a range
+            str->apply(*sp, *st);
+
+            // 5) must implement a method result, with an output iterator
+            str->result(*st, std::back_inserter(*v), true);
+        }
+    };
+
+public :
+    BOOST_CONCEPT_USAGE(ConvexHullStrategy)
+    {
+        check_methods::apply();
+    }
+#endif
+};
+
+
+
+}} // namespace ggl::concept
+
+#endif // GGL_STRATEGIES_CONCEPTS_CONVEX_HULL_CONCEPT_HPP
Added: sandbox/ggl/formal_review/boost/ggl/strategies/concepts/distance_concept.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/strategies/concepts/distance_concept.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,138 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGIES_CONCEPTS_DISTANCE_CONCEPT_HPP
+#define GGL_STRATEGIES_CONCEPTS_DISTANCE_CONCEPT_HPP
+
+#include <vector>
+#include <iterator>
+
+#include <boost/concept_check.hpp>
+
+#include <ggl/geometries/concepts/point_concept.hpp>
+#include <ggl/geometries/segment.hpp>
+
+
+namespace ggl { namespace concept {
+
+
+/*!
+    \brief Checks strategy for point-segment-distance
+    \ingroup distance
+*/
+template <typename Strategy>
+struct PointDistanceStrategy
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+    private :
+
+        // 1) must define first_point_type
+        typedef typename Strategy::first_point_type ptype1;
+        BOOST_CONCEPT_ASSERT
+            (
+                (concept::ConstPoint<ptype1>)
+            );
+
+        // 2) must define second_point_type
+        typedef typename Strategy::second_point_type ptype2;
+        BOOST_CONCEPT_ASSERT
+            (
+                (concept::ConstPoint<ptype2>)
+            );
+
+        // 3) must define return_type
+        typedef typename Strategy::return_type rtype;
+
+        // 4) must implement apply with arguments
+        struct apply_checker
+        {
+            static void check()
+            {
+                Strategy* str;
+                ptype1 *p1;
+                ptype2 *p2;
+                rtype r = str->apply(*p1, *p2);
+
+                boost::ignore_unused_variable_warning(str);
+                boost::ignore_unused_variable_warning(r);
+            }
+        };
+
+    public :
+        BOOST_CONCEPT_USAGE(PointDistanceStrategy)
+        {
+            apply_checker::check();
+        }
+#endif
+};
+
+
+/*!
+    \brief Checks strategy for point-segment-distance
+    \ingroup strategy_concepts
+*/
+template <typename Strategy>
+struct PointSegmentDistanceStrategy
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+    private :
+
+        // 1) must define point_type
+        typedef typename Strategy::point_type ptype;
+        BOOST_CONCEPT_ASSERT
+            (
+                (concept::ConstPoint<ptype>)
+            );
+
+        // 2) must define segment_point_type
+        typedef typename Strategy::segment_point_type sptype;
+        BOOST_CONCEPT_ASSERT
+            (
+                (concept::ConstPoint<sptype>)
+            );
+
+        // 3) must define return_type
+        typedef typename Strategy::return_type rtype;
+
+        // 4) must define underlying point-distance-strategy
+        typedef typename Strategy::point_strategy_type stype;
+        BOOST_CONCEPT_ASSERT
+            (
+                (concept::PointDistanceStrategy<stype>)
+            );
+
+
+        // 5) must implement method apply with arguments
+        struct apply_checker
+        {
+            static void check()
+            {
+                Strategy *str;
+                ptype *p;
+                sptype *sp1;
+                sptype *sp2;
+
+                rtype r = str->apply(*p, *sp1, *sp2);
+
+                boost::ignore_unused_variable_warning(str);
+                boost::ignore_unused_variable_warning(r);
+            }
+        };
+
+    public :
+        BOOST_CONCEPT_USAGE(PointSegmentDistanceStrategy)
+        {
+            apply_checker::check();
+        }
+#endif
+};
+
+
+
+}} // namespace ggl::concept
+
+#endif // GGL_STRATEGIES_CONCEPTS_DISTANCE_CONCEPT_HPP
Added: sandbox/ggl/formal_review/boost/ggl/strategies/concepts/simplify_concept.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/strategies/concepts/simplify_concept.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,72 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGIES_CONCEPTS_SIMPLIFY_CONCEPT_HPP
+#define GGL_STRATEGIES_CONCEPTS_SIMPLIFY_CONCEPT_HPP
+
+#include <vector>
+#include <iterator>
+
+#include <boost/concept_check.hpp>
+
+#include <ggl/strategies/concepts/distance_concept.hpp>
+
+
+namespace ggl { namespace concept {
+
+
+/*!
+    \brief Checks strategy for simplify
+    \ingroup simplify
+*/
+template <typename Strategy>
+struct SimplifyStrategy
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+    private :
+
+        // 1) must define distance_strategy_type,
+        //    defining point-segment distance strategy (to be checked)
+        typedef typename Strategy::distance_strategy_type ds_type;
+
+        BOOST_CONCEPT_ASSERT
+            (
+                (concept::PointSegmentDistanceStrategy<ds_type>)
+            );
+
+        struct apply_checker
+        {
+            static void check()
+            {
+                Strategy *str;
+                std::vector<typename ds_type::point_type> const* v1;
+                std::vector<typename ds_type::point_type> * v2;
+
+                // 2) must implement method apply with arguments
+                //    - Range
+                //    - OutputIterator
+                //    - floating point value
+                str->apply(*v1, std::back_inserter(*v2), 1.0);
+
+                boost::ignore_unused_variable_warning(str);
+            }
+        };
+
+    public :
+        BOOST_CONCEPT_USAGE(SimplifyStrategy)
+        {
+            apply_checker::check();
+
+        }
+#endif
+};
+
+
+
+}} // namespace ggl::concept
+
+#endif // GGL_STRATEGIES_CONCEPTS_SIMPLIFY_CONCEPT_HPP
Added: sandbox/ggl/formal_review/boost/ggl/strategies/concepts/within_concept.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/strategies/concepts/within_concept.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,73 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGIES_CONCEPTS_WITHIN_CONCEPT_HPP
+#define GGL_STRATEGIES_CONCEPTS_WITHIN_CONCEPT_HPP
+
+
+
+#include <boost/concept_check.hpp>
+
+
+namespace ggl { namespace concept {
+
+
+/*!
+    \brief Checks strategy for within (point-in-polygon)
+    \ingroup within
+*/
+template <typename Strategy>
+class WithinStrategy
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+
+    // 1) must define state_type,
+    typedef typename Strategy::state_type state_type;
+
+    // 2) must define point_type (of "point" in poly)
+    typedef typename Strategy::point_type point_type;
+
+    // 3) must define point_type, of polygon (segments)
+    typedef typename Strategy::segment_point_type spoint_type;
+
+
+    struct check_methods
+    {
+        static void apply()
+        {
+            Strategy const* str;
+
+            state_type* st;
+            point_type const* p;
+            spoint_type const* sp;
+
+            // 4) must implement a method apply
+            //    having a point, two segment-points, and state
+            str->apply(*p, *sp, *sp, *st);
+
+            // 5) must implement a method result
+            bool r = str->result(*st);
+
+            boost::ignore_unused_variable_warning(r);
+            boost::ignore_unused_variable_warning(str);
+        }
+    };
+
+
+public :
+    BOOST_CONCEPT_USAGE(WithinStrategy)
+    {
+        check_methods::apply();
+    }
+#endif
+};
+
+
+
+}} // namespace ggl::concept
+
+#endif // GGL_STRATEGIES_CONCEPTS_WITHIN_CONCEPT_HPP
Added: sandbox/ggl/formal_review/boost/ggl/strategies/convex_hull.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/strategies/convex_hull.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,37 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGIES_CONVEX_HULL_HPP
+#define GGL_STRATEGIES_CONVEX_HULL_HPP
+
+#include <ggl/strategies/tags.hpp>
+
+
+namespace ggl
+{
+
+
+
+
+/*!
+    \brief Traits class binding a convex hull calculation strategy to a coordinate system
+    \ingroup convex_hull
+    \tparam Tag tag of coordinate system
+    \tparam Geometry the geometry type (hull operates internally per hull over geometry)
+    \tparam Point point-type of output points
+*/
+template <typename Tag, typename Geometry, typename Point>
+struct strategy_convex_hull
+{
+    typedef strategy::not_implemented type;
+};
+
+
+} // namespace ggl
+
+#endif // GGL_STRATEGIES_CONVEX_HULL_HPP
Added: sandbox/ggl/formal_review/boost/ggl/strategies/distance.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/strategies/distance.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,53 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGIES_DISTANCE_HPP
+#define GGL_STRATEGIES_DISTANCE_HPP
+
+
+#include <ggl/strategies/tags.hpp>
+
+
+namespace ggl
+{
+
+
+/*!
+    \brief Traits class binding a distance strategy to a (possibly two) coordinate system(s)
+    \ingroup distance
+    \tparam T1 tag of coordinate system of first point type
+    \tparam T2 tag of coordinate system of second point type
+    \tparam P1 first point-type
+    \tparam P2 second point-type
+*/
+template <typename T1, typename T2, typename P1, typename P2>
+struct strategy_distance
+{
+    typedef strategy::not_implemented type;
+};
+
+/*!
+    \brief Traits class binding a distance-to-segment strategy to a (possibly two) coordinate system(s)
+    \ingroup distance
+    \tparam CsTag1 tag of coordinate system of point type
+    \tparam CsTag2 tag of coordinate system of segment type, usually same as CsTag1
+    \tparam Point point-type
+    \tparam Segment segment-type
+*/
+template <typename CsTag1, typename CsTag2, typename Point, typename Segment>
+struct strategy_distance_segment
+{
+    typedef strategy::not_implemented type;
+};
+
+
+
+
+} // namespace ggl
+
+#endif // GGL_STRATEGIES_DISTANCE_HPP
Added: sandbox/ggl/formal_review/boost/ggl/strategies/distance_result.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/strategies/distance_result.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,306 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGIES_DISTANCE_RESULT_HPP
+#define GGL_STRATEGIES_DISTANCE_RESULT_HPP
+
+#include <utility>
+#include <cmath>
+#include <limits>
+// #include <iostream>
+
+#include <boost/mpl/if.hpp>
+#include <boost/numeric/conversion/cast.hpp>
+#include <boost/type_traits.hpp>
+
+#include <ggl/core/cs.hpp>
+#include <ggl/core/point_type.hpp>
+#include <ggl/strategies/distance.hpp>
+#include <ggl/util/select_most_precise.hpp>
+
+
+namespace ggl {
+
+/*!
+    \brief Encapsulate the results of distance calculation
+    \ingroup distance
+    \details Distance calculation for xy points or xyz points is done by taking the square
+    root. However, for distance comparison drawing the square root is not necessary.
+    Therefore the distance strategies are allowed to return the squares of the distance.
+    This structure contains the distance, and a boolean to indicate if it is squared.
+    It has an automatic conversion to a double value, which does the square root if necessary.
+    \note Thanks to Phil Endecott for his suggestion to change the pair to the double-convertable
+    http://article.gmane.org/gmane.comp.lib.boost.devel/172709/match=greatcircle_distance
+*/
+template<typename T = double>
+struct cartesian_distance
+{
+    private :
+        T m_squared_distance;
+
+        // Because result is square-rooted, for integer, the cast should
+        // go to double and NOT to T
+        typedef typename
+            boost::mpl::if_c
+            <
+                boost::is_integral<T>::type::value,
+                double,
+                T
+            >::type cast_type;
+
+
+
+
+    public :
+
+
+        /// Constructor with a value
+        explicit cartesian_distance(T const& v) : m_squared_distance(v) {}
+
+        /// Automatic conversion to double or higher precision,
+        /// taking squareroot if necessary
+        inline operator cast_type() const
+        {
+            return boost::numeric_cast<cast_type>
+                (
+#if defined(NUMERIC_ADAPTOR_INCLUDED)
+                    boost::sqrt(
+#else
+                    std::sqrt(
+#endif
+                        boost::numeric_cast
+                            <
+                                typename select_most_precise<cast_type, double>::type
+                            >(m_squared_distance)
+                            )
+                );
+        }
+
+        // Compare squared values
+        inline bool operator<(cartesian_distance<T> const& other) const
+        {
+            return this->m_squared_distance < other.m_squared_distance;
+        }
+        inline bool operator>(cartesian_distance<T> const& other) const
+        {
+            return this->m_squared_distance > other.m_squared_distance;
+        }
+        inline bool operator==(cartesian_distance<T> const& other) const
+        {
+            return this->m_squared_distance == other.m_squared_distance;
+        }
+
+        // Compare just with a corresponding POD value
+        // Note: this is NOT possible because of the cast to double,
+        // it makes it for the compiler ambiguous which to take
+        /*
+        inline bool operator<(T const& value) const
+        {
+            return this->m_squared_distance < (value * value);
+        }
+        inline bool operator>(T const& value) const
+        {
+            return this->m_squared_distance > (value * value);
+        }
+        inline bool operator==(T const& value) const
+        {
+            return this->m_squared_distance == (value * value);
+        }
+        */
+
+        // Utility method to compare without SQRT, but not with method above because for epsilon that
+        // makes no sense...
+        inline bool very_small() const
+        {
+            return m_squared_distance <= std::numeric_limits<T>::epsilon();
+        }
+
+        /// The "squared_value" method returns the internal squared value
+        inline T squared_value() const
+        {
+            return m_squared_distance;
+        }
+
+        /// Make streamable to enable std::cout << ggl::distance( )
+        template <typename Char, typename Traits>
+        inline friend std::basic_ostream<Char, Traits>& 
+                operator<<(std::basic_ostream<Char, Traits>& os,
+                cartesian_distance<T> const& d)
+        {
+            // Avoid "ambiguous function call" for MSVC
+            cast_type const sq = d.m_squared_distance;
+
+            os <<
+#if defined(NUMERIC_ADAPTOR_INCLUDED)
+                boost::sqrt(sq);
+#else
+                std::sqrt(sq);
+#endif
+            return os;
+        }
+
+};
+
+
+
+/*
+
+    From Phil Endecott, on the list:
+
+    You can go further.  If I'm searching through a long list of points to
+    find the closest to P then I'll avoid the squaring (and conversion to
+    double if my co-ordinates are integers) whenever possible.  You can
+    achieve this with a more complex distance proxy:
+
+    class distance_proxy {
+       double dx;
+       double dy;
+       distance_proxy(double dx_, double dy_): dx(dx_), dy(dy_) {}
+       friend pythag_distance(point,point);
+    public:
+       operator double() { return sqrt(dx*dx+dy*dy); }
+       bool operator>(double d) {
+         return dx>d
+             || dy>d
+             || (dx*dx+dy*dy > d*d);
+       }
+    };
+
+    So this is convertible to double, but can be compared to a distance
+    without any need for sqrt() and only multiplication in some cases.
+    Further refinement is possible.
+
+
+    Barend:
+    feasable, needs to be templatized by the number of dimensions. For distance it
+    results in a nice "delayed calculation".
+    For searching you might take another approach, first calculate dx, if OK then dy,
+    if OK then the sqrs. So as above but than distance does not need to be calculated.
+    So it is in fact another strategy.
+
+
+*/
+
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+    namespace distance
+    {
+        template <typename R, typename T>
+        struct distance_result_maker
+        {
+        };
+
+        template <typename R, typename T>
+        struct distance_result_maker<ggl::cartesian_distance<R>, T>
+        {
+            static inline ggl::cartesian_distance<R> apply(T const& value)
+            {
+                return cartesian_distance<R>(value * value);
+            }
+        };
+
+        template <typename T>
+        struct distance_result_maker<double, T>
+        {
+            static inline double apply(T const& value)
+            {
+                return value;
+            }
+        };
+
+
+        template <typename T>
+        struct close_to_zero
+        {
+            static inline bool apply(T const& value)
+            {
+                return value <= std::numeric_limits<T>::epsilon();
+            }
+        };
+
+
+        template <typename T>
+        struct close_to_zero<ggl::cartesian_distance<T> >
+        {
+            static inline bool apply(ggl::cartesian_distance<T> const& value)
+            {
+                return value.very_small();
+            }
+        };
+
+
+    }
+}
+#endif
+
+
+
+/*!
+    \brief Shortcut to define return type of distance strategy
+    \ingroup distance
+    \tparam Geometry1 first geometry
+    \tparam Geometry2 second geometry
+ */
+template <typename Geometry1, typename Geometry2 = Geometry1>
+struct distance_result
+{
+    typedef typename point_type<Geometry1>::type point_type1;
+    typedef typename point_type<Geometry2>::type point_type2;
+    typedef typename strategy_distance
+        <
+            typename cs_tag<point_type1>::type,
+            typename cs_tag<point_type2>::type,
+            point_type1,
+            point_type2
+        >::type strategy_type;
+    typedef typename strategy_type::return_type type;
+};
+
+
+
+
+
+/*!
+    \brief Object generator to create instance which can be compared
+    \ingroup distance
+    \details If distance results have to be compared to a certain value it makes sense to use
+    this function to generate a distance result of a certain value, and compare the distance
+    result with this instance. SQRT calculations are then avoided
+    \tparam R distance result type
+    \tparam T arithmetic type, e.g. double
+    \param value the distance to compare with
+    \return the distance result
+*/
+template <typename R, typename T>
+inline R make_distance_result(T const& value)
+{
+    return detail::distance::distance_result_maker<R, T>::apply(value);
+}
+
+
+/*!
+    \brief Utility function to check if a distance is very small
+    \ingroup distance
+    \details Depending on the "distance result" type it checks if it is smaller than epsilon,
+    or (for Cartesian distances) if the square is smaller than epsilon
+    \tparam R the distance result type, either arithmetic or cartesian distance
+    \param value the distance result to check
+*/
+template <typename T>
+inline bool close_to_zero(T const& value)
+{
+    return detail::distance::close_to_zero<T>::apply(value);
+}
+
+} // namespace ggl
+
+
+#endif // GGL_STRATEGIES_DISTANCE_RESULT_HPP
Added: sandbox/ggl/formal_review/boost/ggl/strategies/intersection_result.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/strategies/intersection_result.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,167 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGIES_INTERSECTION_RESULT_HPP
+#define GGL_STRATEGIES_INTERSECTION_RESULT_HPP
+
+#if defined(HAVE_MATRIX_AS_STRING)
+#include <string>
+#endif
+
+namespace ggl
+{
+
+/*!
+    \brief Dimensionally Extended 9 Intersection Matrix
+    \details
+    \ingroup overlay
+    \see http://gis.hsr.ch/wiki/images/3/3d/9dem_springer.pdf
+*/
+struct de9im
+{
+    int ii, ib, ie,
+        bi, bb, be,
+        ei, eb, ee;
+
+    inline de9im()
+        : ii(-1), ib(-1), ie(-1)
+        , bi(-1), bb(-1), be(-1)
+        , ei(-1), eb(-1), ee(-1)
+    {
+    }
+
+    inline de9im(int ii0, int ib0, int ie0,
+        int bi0, int bb0, int be0,
+        int ei0, int eb0, int ee0)
+        : ii(ii0), ib(ib0), ie(ie0)
+        , bi(bi0), bb(bb0), be(be0)
+        , ei(ei0), eb(eb0), ee(ee0)
+    {}
+
+    inline bool equals() const
+    {
+        return ii >= 0 && ie < 0 && be < 0 && ei < 0 && eb < 0;
+    }
+
+    inline bool disjoint() const
+    {
+        return ii < 0 && ib < 0 && bi < 0 && bb < 0;
+    }
+
+    inline bool intersects() const
+    {
+        return ii >= 0 || bb >= 0 || bi >= 0 || ib >= 0;
+    }
+
+    inline bool touches() const
+    {
+        return ii < 0 && (bb >= 0 || bi >= 0 || ib >= 0);
+    }
+
+    inline bool crosses() const
+    {
+        return (ii >= 0 && ie >= 0) || (ii == 0);
+    }
+
+    inline bool overlaps() const
+    {
+        return ii >= 0 && ie >= 0 && ei >= 0;
+    }
+
+    inline bool within() const
+    {
+        return ii >= 0 && ie < 0 && be < 0;
+    }
+
+    inline bool contains() const
+    {
+        return ii >= 0 && ei < 0 && eb < 0;
+    }
+
+
+    static inline char as_char(int v)
+    {
+        return v >= 0 && v < 10 ? ('0' + char(v)) : '-';
+    }
+
+#if defined(HAVE_MATRIX_AS_STRING)
+    inline std::string matrix_as_string(std::string const& tab, std::string const& nl) const
+    {
+        std::string ret;
+        ret.reserve(9 + tab.length() * 3 + nl.length() * 3);
+        ret += tab; ret += as_char(ii); ret += as_char(ib); ret += as_char(ie); ret += nl;
+        ret += tab; ret += as_char(bi); ret += as_char(bb); ret += as_char(be); ret += nl;
+        ret += tab; ret += as_char(ei); ret += as_char(eb); ret += as_char(ee);
+        return ret;
+    }
+
+    inline std::string matrix_as_string() const
+    {
+        return matrix_as_string("", "");
+    }
+#endif
+
+};
+
+struct de9im_segment : public de9im
+{
+    bool collinear; // true if segments are aligned (for equal,overlap,touch)
+    bool opposite; // true if direction is reversed (for equal,overlap,touch)
+    bool parallel;  // true if disjoint but parallel
+    bool degenerate; // true for segment(s) of zero length
+
+    double ra, rb; // temp
+
+    inline de9im_segment()
+        : de9im()
+        , collinear(false)
+        , opposite(false)
+        , parallel(false)
+        , degenerate(false)
+    {}
+
+    inline de9im_segment(double a, double b,
+        int ii0, int ib0, int ie0,
+        int bi0, int bb0, int be0,
+        int ei0, int eb0, int ee0,
+        bool c = false, bool o = false, bool p = false, bool d = false)
+        : de9im(ii0, ib0, ie0, bi0, bb0, be0, ei0, eb0, ee0)
+        , collinear(c)
+        , opposite(o)
+        , parallel(p)
+        , degenerate(d)
+        , ra(a), rb(b)
+    {}
+
+
+#if defined(HAVE_MATRIX_AS_STRING)
+    inline std::string as_string() const
+    {
+        std::string ret = matrix_as_string();
+        ret += collinear ? "c" : "-";
+        ret += opposite ? "o" : "-";
+        return ret;
+    }
+#endif
+};
+
+template <typename P>
+struct segment_intersection_points
+{
+    int count;
+    P intersections[2];
+
+    segment_intersection_points()
+        : count(0)
+    {}
+};
+
+} // namespace ggl
+
+
+#endif // GGL_STRATEGIES_INTERSECTION_RESULT_HPP
Added: sandbox/ggl/formal_review/boost/ggl/strategies/length_result.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/strategies/length_result.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,40 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGIES_LENGTH_RESULT_HPP
+#define GGL_STRATEGIES_LENGTH_RESULT_HPP
+
+
+#include <ggl/core/coordinate_type.hpp>
+#include <ggl/util/select_most_precise.hpp>
+
+
+namespace ggl
+{
+
+/*!
+    \brief Meta-function defining return type of length function
+    \ingroup length
+    \note Length of a line of integer coordinates can be double.
+        So we take at least a double. If Big Number types are used,
+        we take that type.
+
+ */
+template <typename Geometry>
+struct length_result
+{
+    typedef typename select_most_precise
+        <
+            typename coordinate_type<Geometry>::type,
+            long double
+        >::type type;
+};
+
+} // namespace ggl
+
+
+#endif // GGL_STRATEGIES_LENGTH_RESULT_HPP
Added: sandbox/ggl/formal_review/boost/ggl/strategies/parse.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/strategies/parse.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,36 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGIES_PARSE_HPP
+#define GGL_STRATEGIES_PARSE_HPP
+
+#include <ggl/strategies/tags.hpp>
+
+
+namespace ggl
+{
+
+
+
+/*!
+    \brief Tagraits class binding a parsing strategy to a coordinate system
+    \ingroup parse
+    \tparam Tag tag of coordinate system of point-type
+    \tparam CoordinateSystem coordinate system
+*/
+template <typename Tag, typename CoordinateSystem>
+struct strategy_parse
+{
+    typedef strategy::not_implemented type;
+};
+
+
+
+} // namespace ggl
+
+#endif // GGL_STRATEGIES_PARSE_HPP
Added: sandbox/ggl/formal_review/boost/ggl/strategies/point_in_poly.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/strategies/point_in_poly.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,36 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGIES_POINT_IN_POLY_HPP
+#define GGL_STRATEGIES_POINT_IN_POLY_HPP
+
+#include <ggl/strategies/tags.hpp>
+
+namespace ggl
+{
+
+
+/*!
+    \brief Traits class binding a within determination strategy to a coordinate system
+    \ingroup within
+    \tparam TagPoint tag of coordinate system of point-type
+    \tparam TagSegment tag of coordinate system of segment-type
+    \tparam Point point-type of input points
+    \tparam PointOfSegment point-type of input segment-points
+*/
+template <typename TagPoint, typename TagSegment, typename Point, typename PointOfSegment>
+struct strategy_within
+{
+    typedef strategy::not_implemented type;
+};
+
+
+
+} // namespace ggl
+
+#endif // GGL_STRATEGIES_POINT_IN_POLY_HPP
Added: sandbox/ggl/formal_review/boost/ggl/strategies/side.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/strategies/side.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,34 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGIES_SIDE_HPP
+#define GGL_STRATEGIES_SIDE_HPP
+
+
+#include <ggl/strategies/tags.hpp>
+
+
+namespace ggl
+{
+
+
+/*!
+    \brief Traits class binding a side determination strategy to a coordinate system
+    \ingroup util
+    \tparam Tag tag of coordinate system of point-type
+*/
+template <typename Tag>
+struct strategy_side
+{
+    typedef strategy::not_implemented type;
+};
+
+
+} // namespace ggl
+
+#endif // GGL_STRATEGIES_SIDE_HPP
Added: sandbox/ggl/formal_review/boost/ggl/strategies/spherical/area_huiller.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/strategies/spherical/area_huiller.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,152 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGIES_SPHERICAL_AREA_HUILLER_HPP
+#define GGL_STRATEGIES_SPHERICAL_AREA_HUILLER_HPP
+
+
+#include <ggl/strategies/spherical/distance_haversine.hpp>
+
+#include <ggl/core/radian_access.hpp>
+
+
+namespace ggl
+{
+
+namespace strategy { namespace area {
+
+
+
+/*!
+    \brief Area calculation by spherical excess / Huiller's formula
+    \tparam P type of points of rings/polygons
+    \author Barend Gehrels. Adapted from:
+    - http://www.soe.ucsc.edu/~pang/160/f98/Gems/GemsIV/sph_poly.c
+    - http://williams.best.vwh.net/avform.htm
+    \note The version in Gems didn't account for polygons crossing the 180 meridian.
+    \note This version works for convex and non-convex polygons, for 180 meridian
+    crossing polygons and for polygons with holes. However, some cases (especially
+    180 meridian cases) must still be checked.
+    \note The version which sums angles, which is often seen, doesn't handle non-convex
+    polygons correctly.
+    \note The version which sums longitudes, see
+    http://trs-new.jpl.nasa.gov/dspace/bitstream/2014/40409/1/07-03.pdf, is simple
+    and works well in most cases but not in 180 meridian crossing cases. This probably
+    could be solved.
+*/
+template
+<
+    typename PointOfSegment,
+    typename CalculationType = void
+>
+class huiller
+{
+protected :
+    struct excess_sum
+    {
+        double sum;
+
+        // Distances are calculated on unit sphere here
+        strategy::distance::haversine<PointOfSegment, PointOfSegment>
+                distance_over_unit_sphere;
+
+
+        inline excess_sum()
+            : sum(0)
+            , distance_over_unit_sphere(1)
+        {}
+        inline double area(double radius) const
+        {
+            return - sum * radius * radius;
+        }
+    };
+
+public :
+    typedef double return_type;
+    typedef PointOfSegment segment_point_type;
+    typedef excess_sum state_type;
+
+    inline huiller(double radius = 1.0)
+        : m_radius(radius)
+    {}
+
+    inline void apply(PointOfSegment const& p1,
+                PointOfSegment const& p2,
+                excess_sum& state) const
+    {
+        if (! ggl::math::equals(get<0>(p1), get<0>(p2)))
+        {
+            // Distance p1 p2
+            double a = state.distance_over_unit_sphere.apply(p1, p2);
+
+            // Sides on unit sphere to south pole
+            double b = 0.5 * math::pi - ggl::get_as_radian<1>(p2);
+            double c = 0.5 * math::pi - ggl::get_as_radian<1>(p1);
+
+            // Semi parameter
+            double s = 0.5 * (a + b + c);
+
+            // E: spherical excess, using l'Huiller's formula
+            // [tg(e / 4)]2   =   tg[s / 2]  tg[(s-a) / 2]  tg[(s-b) / 2]  tg[(s-c) / 2]
+            double E = 4.0 * atan(sqrt(std::abs(tan(s / 2)
+                    * tan((s - a) / 2)
+                    * tan((s - b) / 2)
+                    * tan((s - c) / 2))));
+
+            E = std::abs(E);
+
+            // In right direction: positive, add area. In left direction: negative, subtract area.
+            // Longitude comparisons are not so obvious. If one is negative, other is positive,
+            // we have to take the dateline into account.
+            // TODO: check this / enhance this, should be more robust. See also the "grow" for ll
+            // TODO: use minmax or "smaller"/"compare" strategy for this
+            double lon1 = ggl::get_as_radian<0>(p1) < 0
+                ? ggl::get_as_radian<0>(p1) + math::two_pi
+                : ggl::get_as_radian<0>(p1);
+
+            double lon2 = ggl::get_as_radian<0>(p2) < 0
+                ? ggl::get_as_radian<0>(p2) + math::two_pi
+                : ggl::get_as_radian<0>(p2);
+
+            if (lon2 < lon1)
+            {
+                E = -E;
+            }
+
+            state.sum += E;
+        }
+    }
+
+    inline return_type result(excess_sum const& state) const
+    {
+        return state.area(m_radius);
+    }
+
+private :
+    /// Radius of the sphere
+    double m_radius;
+};
+
+
+}} // namespace strategy::area
+
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+template <typename Point>
+struct strategy_area<spherical_tag, Point>
+{
+    typedef strategy::area::huiller<Point> type;
+};
+
+#endif
+
+} // namespace ggl
+
+#endif // GGL_STRATEGIES_SPHERICAL_AREA_HUILLER_HPP
Added: sandbox/ggl/formal_review/boost/ggl/strategies/spherical/compare_circular.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/strategies/spherical/compare_circular.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,154 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGIES_SPHERICAL_COMPARE_SPHERICAL_HPP
+#define GGL_STRATEGIES_SPHERICAL_COMPARE_SPHERICAL_HPP
+
+
+#include <ggl/core/cs.hpp>
+#include <ggl/core/tags.hpp>
+
+
+#include <ggl/strategies/compare.hpp>
+
+
+namespace ggl
+{
+
+namespace strategy { namespace compare {
+
+
+namespace detail {
+
+
+template <typename Units>
+struct shift
+{
+};
+
+
+template <>
+struct shift<degree>
+{
+    static inline double full() { return 360.0; }
+    static inline double half() { return 180.0; }
+};
+
+template <>
+struct shift<radian>
+{
+    static inline double full() { return ggl::math::two_pi; }
+    static inline double half() { return ggl::math::pi; }
+};
+
+} // namespace detail
+
+/*!
+    \brief Compare (in one direction) strategy for spherical coordinates
+    \ingroup util
+    \tparam Point point-type
+    \tparam Dimension dimension
+*/
+template <typename CoordinateType, typename Units, typename Compare>
+struct circular_comparator
+{
+    static inline CoordinateType put_in_range(CoordinateType const& c,
+            double min_border, double max_border)
+    {
+        CoordinateType value = c;
+        while (value < min_border)
+        {
+            value += detail::shift<Units>::full();
+        }
+        while (value > max_border)
+        {
+            value -= detail::shift<Units>::full();
+        }
+        return value;
+    }
+
+    inline bool operator()(CoordinateType const& c1, CoordinateType const& c2)  const
+    {
+        Compare compare;
+
+        // Check situation that one of them is e.g. std::numeric_limits.
+        static const double full = detail::shift<Units>::full();
+        double mx = 10.0 * full;
+        if (c1 < -mx || c1 > mx || c2 < -mx || c2 > mx)
+        {
+            // do normal comparison, using circular is not useful
+            return compare(c1, c2);
+        }
+
+        static const double half = full / 2.0;
+        CoordinateType v1 = put_in_range(c1, -half, half);
+        CoordinateType v2 = put_in_range(c2, -half, half);
+
+        // Two coordinates on a circle are
+        // at max <= half a circle away from each other.
+        // So if it is more, shift origin.
+        CoordinateType diff = std::abs(v1 - v2);
+        if (diff > half)
+        {
+            v1 = put_in_range(v1, 0, full);
+            v2 = put_in_range(v2, 0, full);
+        }
+
+        return compare(v1, v2);
+    }
+};
+
+
+}} // namespace strategy::compare
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+// Specialize for the longitude (dim 0)
+template
+<
+    typename Point,
+    template<typename> class CoordinateSystem,
+    typename Units
+>
+struct strategy_compare<spherical_tag, 1, Point, CoordinateSystem<Units>, 0>
+{
+    typedef typename coordinate_type<Point>::type coordinate_type;
+    typedef strategy::compare::circular_comparator
+        <
+            coordinate_type,
+            Units,
+            std::less<coordinate_type>
+        > type;
+};
+
+template
+<
+    typename Point,
+    template<typename> class CoordinateSystem,
+    typename Units
+>
+struct strategy_compare<spherical_tag, -1, Point, CoordinateSystem<Units>, 0>
+{
+    typedef typename coordinate_type<Point>::type coordinate_type;
+    typedef strategy::compare::circular_comparator
+        <
+            coordinate_type,
+            Units,
+            std::greater<coordinate_type>
+        > type;
+};
+
+
+
+#endif
+
+
+} // namespace ggl
+
+
+#endif // GGL_STRATEGIES_SPHERICAL_COMPARE_SPHERICAL_HPP
Added: sandbox/ggl/formal_review/boost/ggl/strategies/spherical/distance_cross_track.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/strategies/spherical/distance_cross_track.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,158 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGIES_SPHERICAL_DISTANCE_CROSS_TRACK_HPP
+#define GGL_STRATEGIES_SPHERICAL_DISTANCE_CROSS_TRACK_HPP
+
+#include <boost/concept/requires.hpp>
+
+
+#include <ggl/core/cs.hpp>
+#include <ggl/core/access.hpp>
+#include <ggl/core/radian_access.hpp>
+
+
+#include <ggl/strategies/distance.hpp>
+#include <ggl/strategies/concepts/distance_concept.hpp>
+
+#include <ggl/util/math.hpp>
+//#include <ggl/util/write_dsv.hpp>
+
+
+
+namespace ggl
+{
+
+namespace strategy { namespace distance {
+
+/*!
+    \brief Strategy functor for distance point to segment calculation
+    \ingroup distance
+    \details Class which calculates the distance of a point to a segment, using latlong points
+    \see http://williams.best.vwh.net/avform.htm
+    \tparam P point type
+    \tparam S segment type
+*/
+template <typename Point, typename PointOfSegment>
+class cross_track
+{
+public :
+    typedef double return_type;
+    typedef Point point_type;
+    typedef PointOfSegment segment_point_type;
+
+    typedef typename strategy_distance
+        <
+            typename ggl::cs_tag<Point>::type,
+            typename ggl::cs_tag<Point>::type,
+            Point, Point
+        >::type point_strategy_type;
+
+    BOOST_CONCEPT_ASSERT
+        (
+            (ggl::concept::PointDistanceStrategy<point_strategy_type>)
+        );
+
+
+
+    inline cross_track(double r = 1.0)
+        : m_radius(r)
+        , m_strategy(1.0) // Keep this 1.0 and not r
+    {}
+
+
+    // It might be useful in the future
+    // to overload constructor with strategy info.
+    // crosstrack(...) {}
+
+
+    inline return_type apply(Point const& p,
+                PointOfSegment const& sp1, PointOfSegment const& sp2) const
+    {
+        // http://williams.best.vwh.net/avform.htm#XTE
+        double d1 = m_strategy.apply(sp1, p);
+
+        // Actually, calculation of d2 not necessary if we know that the projected point is on the great circle...
+        double d2 = m_strategy.apply(sp2, p);
+
+        double crs_AD = course(sp1, p);
+        double crs_AB = course(sp1, sp2);
+        double XTD = std::abs(asin(sin(d1) * sin(crs_AD - crs_AB)));
+
+//std::cout << "Course " << dsv(sp1) << " to " << dsv(p) << " " << crs_AD * ggl::math::r2d << std::endl;
+//std::cout << "Course " << dsv(sp1) << " to " << dsv(sp2) << " " << crs_AB * ggl::math::r2d << std::endl;
+//std::cout << "XTD: " << (XTD * 6373.0) << " d1: " <<  (d1 * 6373.0)  << " d2: " <<  (d2 * 6373.0)  << std::endl;
+
+
+        // Return shortest distance, either to projected point on segment sp1-sp2, or to sp1, or to sp2
+        return return_type(m_radius * (std::min)((std::min)(d1, d2), XTD));
+    }
+
+private :
+    double m_radius;
+
+    // Point-point distances are calculated in radians, on the unit sphere
+    point_strategy_type m_strategy;
+
+    /// Calculate course (bearing) between two points. Might be moved to a "course formula" ...
+    inline double course(Point const& p1, Point const& p2) const
+    {
+        // http://williams.best.vwh.net/avform.htm#Crs
+        double dlon = get_as_radian<0>(p2) - get_as_radian<0>(p1);
+        double cos_p2lat = cos(get_as_radian<1>(p2));
+
+        // "An alternative formula, not requiring the pre-computation of d"
+        return atan2(sin(dlon) * cos_p2lat,
+            cos(get_as_radian<1>(p1)) * sin(get_as_radian<1>(p2))
+            - sin(get_as_radian<1>(p1)) * cos_p2lat * cos(dlon));
+    }
+
+};
+
+
+}} // namespace strategy::distance
+
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+template <typename Point, typename Segment>
+struct strategy_distance_segment<spherical_tag, spherical_tag, Point, Segment>
+{
+    typedef strategy::distance::cross_track<Point, Segment> type;
+};
+
+
+// Use this point-segment for geographic as well. TODO: change this, extension!
+template <typename Point, typename Segment>
+struct strategy_distance_segment<geographic_tag, geographic_tag, Point, Segment>
+{
+    typedef strategy::distance::cross_track<Point, Segment> type;
+};
+
+
+template <typename Point, typename Segment>
+struct strategy_tag<strategy::distance::cross_track<Point, Segment> >
+{
+    typedef strategy_tag_distance_point_segment type;
+};
+
+
+
+#endif
+
+
+
+
+
+
+} // namespace ggl
+
+
+#endif // GGL_STRATEGIES_SPHERICAL_DISTANCE_CROSS_TRACK_HPP
Added: sandbox/ggl/formal_review/boost/ggl/strategies/spherical/distance_haversine.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/strategies/spherical/distance_haversine.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,115 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGIES_SPHERICAL_DISTANCE_HAVERSINE_HPP
+#define GGL_STRATEGIES_SPHERICAL_DISTANCE_HAVERSINE_HPP
+
+
+#include <ggl/core/cs.hpp>
+#include <ggl/core/access.hpp>
+#include <ggl/core/radian_access.hpp>
+
+
+#include <ggl/strategies/distance.hpp>
+
+#include <ggl/strategies/distance_result.hpp>
+
+
+namespace ggl
+{
+
+namespace strategy { namespace distance {
+
+/*!
+    \brief Distance calculation for spherical coordinates
+        on a perfect sphere using haversine
+    \ingroup distance
+    \tparam P1 first point type
+    \tparam P2 optional second point type
+    \author Adapted from: http://williams.best.vwh.net/avform.htm
+    \see http://en.wikipedia.org/wiki/Great-circle_distance
+    \note It says: <em>The great circle distance d between two
+        points with coordinates {lat1,lon1} and {lat2,lon2} is given by:
+                d=acos(sin(lat1)*sin(lat2)+cos(lat1)*cos(lat2)*cos(lon1-lon2))
+            A mathematically equivalent formula, which is less subject
+                to rounding error for short distances is:
+                d=2*asin(sqrt((sin((lat1-lat2)/2))^2
+                + cos(lat1)*cos(lat2)*(sin((lon1-lon2)/2))^2))
+                </em>
+*/
+template <typename Point1, typename Point2 = Point1>
+class haversine
+{
+public :
+    typedef Point1 first_point_type;
+    typedef Point2 second_point_type;
+    typedef double return_type;
+
+    inline haversine(double r = 1.0)
+        : m_radius(r)
+    {}
+
+    inline return_type apply(Point1 const& p1, Point2 const& p2) const
+    {
+        return calculate(get_as_radian<0>(p1), get_as_radian<1>(p1),
+                        get_as_radian<0>(p2), get_as_radian<1>(p2));
+    }
+
+private :
+    double m_radius;
+    typedef typename coordinate_type<Point1>::type coordinate_type1;
+    typedef typename coordinate_type<Point2>::type coordinate_type2;
+
+    inline return_type calculate(coordinate_type1 const& lon1,
+            coordinate_type1 const& lat1,
+            coordinate_type2 const& lon2,
+            coordinate_type2 const& lat2) const
+    {
+        double a = math::hav(lat2 - lat1)
+                + cos(lat1) * cos(lat2) * math::hav(lon2 - lon1);
+        double c = 2.0 * asin(sqrt(a));
+        return return_type(m_radius * c);
+    }
+};
+
+
+}} // namespace strategy::distance
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+template <typename P1, typename P2>
+struct strategy_distance<spherical_tag, spherical_tag, P1, P2>
+{
+    typedef strategy::distance::haversine<P1, P2> type;
+};
+
+
+
+
+
+
+template <typename P1, typename P2>
+struct strategy_tag<strategy::distance::haversine<P1, P2> >
+{
+    typedef strategy_tag_distance_point_point type;
+};
+
+
+
+
+#endif
+
+
+
+
+
+
+} // namespace ggl
+
+
+#endif // GGL_STRATEGIES_SPHERICAL_DISTANCE_HAVERSINE_HPP
Added: sandbox/ggl/formal_review/boost/ggl/strategies/strategies.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/strategies/strategies.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,49 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGIES_HPP
+#define GGL_STRATEGIES_HPP
+
+
+#include <ggl/strategies/tags.hpp>
+
+#include <ggl/strategies/area.hpp>
+#include <ggl/strategies/centroid.hpp>
+#include <ggl/strategies/compare.hpp>
+#include <ggl/strategies/convex_hull.hpp>
+#include <ggl/strategies/distance.hpp>
+#include <ggl/strategies/parse.hpp>
+#include <ggl/strategies/point_in_poly.hpp>
+#include <ggl/strategies/side.hpp>
+#include <ggl/strategies/transform.hpp>
+
+#include <ggl/strategies/cartesian/area_by_triangles.hpp>
+#include <ggl/strategies/cartesian/centroid_bashein_detmer.hpp>
+#include <ggl/strategies/cartesian/distance_pythagoras.hpp>
+#include <ggl/strategies/cartesian/distance_projected_point.hpp>
+#include <ggl/strategies/cartesian/point_in_poly_franklin.hpp>
+#include <ggl/strategies/cartesian/point_in_poly_crossings_multiply.hpp>
+#include <ggl/strategies/cartesian/side_by_triangle.hpp>
+
+#include <ggl/strategies/spherical/area_huiller.hpp>
+#include <ggl/strategies/spherical/distance_haversine.hpp>
+#include <ggl/strategies/spherical/distance_cross_track.hpp>
+#include <ggl/strategies/spherical/compare_circular.hpp>
+
+#include <ggl/strategies/agnostic/hull_graham_andrew.hpp>
+#include <ggl/strategies/agnostic/point_in_poly_winding.hpp>
+#include <ggl/strategies/agnostic/simplify_douglas_peucker.hpp>
+
+#include <ggl/strategies/strategy_transform.hpp>
+
+#include <ggl/strategies/transform/matrix_transformers.hpp>
+#include <ggl/strategies/transform/map_transformer.hpp>
+#include <ggl/strategies/transform/inverse_transformer.hpp>
+
+
+#endif // GGL_STRATEGIES_HPP
Added: sandbox/ggl/formal_review/boost/ggl/strategies/strategy_transform.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/strategies/strategy_transform.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,358 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGIES_STRATEGY_TRANSFORM_HPP
+#define GGL_STRATEGIES_STRATEGY_TRANSFORM_HPP
+
+#include <cstddef>
+#include <cmath>
+#include <functional>
+
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <ggl/arithmetic/arithmetic.hpp>
+#include <ggl/core/access.hpp>
+#include <ggl/core/coordinate_dimension.hpp>
+
+#include <ggl/util/copy.hpp>
+#include <ggl/util/math.hpp>
+#include <ggl/util/select_coordinate_type.hpp>
+
+namespace ggl
+{
+
+namespace strategy { namespace transform {
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+template
+<
+    typename Src, typename Dst,
+    std::size_t D, std::size_t N,
+    template <typename> class F
+>
+struct transform_coordinates
+{
+    static inline void transform(const Src& source, Dst& dest, double value)
+    {
+        typedef typename select_coordinate_type<Src, Dst>::type coordinate_type;
+
+        F<coordinate_type> function;
+        set<D>(dest, boost::numeric_cast<coordinate_type>(function(get<D>(source), value)));
+        transform_coordinates<Src, Dst, D + 1, N, F>::transform(source, dest, value);
+    }
+};
+
+template
+<
+    typename Src, typename Dst,
+    std::size_t N,
+    template <typename> class F
+>
+struct transform_coordinates<Src, Dst, N, N, F>
+{
+    static inline void transform(const Src& source, Dst& dest, double value)
+    {
+    }
+};
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+/*!
+    \brief Transformation strategy to copy one point to another using assignment operator
+    \ingroup transform
+    \tparam P point type
+ */
+template <typename P>
+struct copy_direct
+{
+    inline bool operator()(const P& p1, P& p2) const
+    {
+        p2 = p1;
+        return true;
+    }
+};
+
+/*!
+    \brief Transformation strategy to do copy a point, copying per coordinate.
+    \ingroup transform
+    \tparam P1 first point type
+    \tparam P2 second point type
+ */
+template <typename P1, typename P2>
+struct copy_per_coordinate
+{
+    inline bool operator()(P1 const& p1, P2& p2) const
+    {
+        // Defensive check, dimensions are equal, selected by specialization
+        assert_dimension_equal<P1, P2>();
+
+        copy_coordinates(p1, p2);
+        return true;
+    }
+};
+
+
+/*!
+    \brief Transformation strategy to go from degree to radian and back
+    \ingroup transform
+    \tparam P1 first point type
+    \tparam P2 second point type
+    \tparam F additional functor to divide or multiply with d2r
+ */
+template <typename P1, typename P2, template <typename> class F>
+struct degree_radian_vv
+{
+    inline bool operator()(P1 const& p1, P2& p2) const
+    {
+        // Spherical coordinates always have 2 coordinates measured in angles
+        // The optional third one is distance/height, provided in another strategy
+        // Polar coordinates having one angle, will be also in another strategy
+        assert_dimension<P1, 2>();
+        assert_dimension<P2, 2>();
+
+        detail::transform_coordinates<P1, P2, 0, 2, F>::transform(p1, p2, math::d2r);
+        return true;
+    }
+};
+
+template <typename P1, typename P2, template <typename> class F>
+struct degree_radian_vv_3
+{
+    inline bool operator()(P1 const& p1, P2& p2) const
+    {
+        assert_dimension<P1, 3>();
+        assert_dimension<P2, 3>();
+
+        detail::transform_coordinates<P1, P2, 0, 2, F>::transform(p1, p2, math::d2r);
+        // Copy height or other third dimension
+        set<2>(p2, get<2>(p1));
+        return true;
+    }
+};
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+    /// Helper function for conversion, phi/theta are in radians
+    template <typename P>
+    inline void spherical_to_cartesian(double phi, double theta, double r, P& p)
+    {
+        assert_dimension<P, 3>();
+
+        // http://en.wikipedia.org/wiki/List_of_canonical_coordinate_transformations#From_spherical_coordinates
+        // Phi = first, theta is second, r is third, see documentation on cs::spherical
+        double const sin_theta = std::sin(theta);
+        set<0>(p, r * sin_theta * std::cos(phi));
+        set<1>(p, r * sin_theta * std::sin(phi));
+        set<2>(p, r * std::cos(theta));
+    }
+
+    /// Helper function for conversion
+    template <typename P>
+    inline bool cartesian_to_spherical2(double x, double y, double z, P& p)
+    {
+        assert_dimension<P, 2>();
+
+        // http://en.wikipedia.org/wiki/List_of_canonical_coordinate_transformations#From_Cartesian_coordinates
+
+        // TODO: MAYBE ONLY IF TO BE CHECKED?
+        double const r = std::sqrt(x * x + y * y + z * z);
+
+        // Unit sphere, r should be 1
+        typedef typename coordinate_type<P>::type coordinate_type;
+        if (std::abs(r - 1.0) > std::numeric_limits<coordinate_type>::epsilon())
+        {
+            return false;
+        }
+        // end todo
+
+        set_from_radian<0>(p, std::atan2(y, x));
+        set_from_radian<1>(p, std::acos(z));
+        return true;
+    }
+
+    template <typename P>
+    inline bool cartesian_to_spherical3(double x, double y, double z, P& p)
+    {
+        assert_dimension<P, 3>();
+
+        // http://en.wikipedia.org/wiki/List_of_canonical_coordinate_transformations#From_Cartesian_coordinates
+        double const r = std::sqrt(x * x + y * y + z * z);
+        set<2>(p, r);
+        set_from_radian<0>(p, std::atan2(y, x));
+        if (r > 0.0)
+        {
+            set_from_radian<1>(p, std::acos(z / r));
+            return true;
+        }
+        return false;
+    }
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+
+/*!
+    \brief Transformation strategy for 2D spherical (phi,theta) to 3D cartesian (x,y,z)
+    \details on Unit sphere
+    \ingroup transform
+    \tparam P1 first point type
+    \tparam P2 second point type
+ */
+template <typename P1, typename P2>
+struct from_spherical_2_to_cartesian_3
+{
+    inline bool operator()(P1 const& p1, P2& p2) const
+    {
+        assert_dimension<P1, 2>();
+        detail::spherical_to_cartesian(get_as_radian<0>(p1), get_as_radian<1>(p1), 1.0, p2);
+        return true;
+    }
+};
+
+/*!
+    \brief Transformation strategy for 3D spherical (phi,theta,r) to 3D cartesian (x,y,z)
+    \ingroup transform
+    \tparam P1 first point type
+    \tparam P2 second point type
+ */
+template <typename P1, typename P2>
+struct from_spherical_3_to_cartesian_3
+{
+    inline bool operator()(P1 const& p1, P2& p2) const
+    {
+        assert_dimension<P1, 3>();
+        detail::spherical_to_cartesian(
+                    get_as_radian<0>(p1), get_as_radian<1>(p1), get<2>(p1), p2);
+        return true;
+    }
+};
+
+/*!
+    \brief Transformation strategy for 3D cartesian (x,y,z) to 2D spherical (phi,theta)
+    \details on Unit sphere
+    \ingroup transform
+    \tparam P1 first point type
+    \tparam P2 second point type
+    \note If x,y,z point is not lying on unit sphere, transformation will return false
+ */
+template <typename P1, typename P2>
+struct from_cartesian_3_to_spherical_2
+{
+    inline bool operator()(P1 const& p1, P2& p2) const
+    {
+        assert_dimension<P1, 3>();
+        return detail::cartesian_to_spherical2(get<0>(p1), get<1>(p1), get<2>(p1), p2);
+    }
+};
+
+
+/*!
+    \brief Transformation strategy for 3D cartesian (x,y,z) to 3D spherical (phi,theta,r)
+    \ingroup transform
+    \tparam P1 first point type
+    \tparam P2 second point type
+ */
+template <typename P1, typename P2>
+struct from_cartesian_3_to_spherical_3
+{
+    inline bool operator()(P1 const& p1, P2& p2) const
+    {
+        assert_dimension<P1, 3>();
+        return detail::cartesian_to_spherical3(get<0>(p1), get<1>(p1), get<2>(p1), p2);
+    }
+};
+
+}} // namespace strategy::transform
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+/// Specialization for same coordinate system family, same system, same dimension, same point type, can be copied
+template <typename CoordSysTag, typename CoordSys, std::size_t D, typename P>
+struct strategy_transform<CoordSysTag, CoordSysTag, CoordSys, CoordSys, D, D, P, P>
+{
+    typedef strategy::transform::copy_direct<P> type;
+};
+
+/// Specialization for same coordinate system family and system, same dimension, different point type, copy per coordinate
+template <typename CoordSysTag, typename CoordSys, std::size_t D, typename P1, typename P2>
+struct strategy_transform<CoordSysTag, CoordSysTag, CoordSys, CoordSys, D, D, P1, P2>
+{
+    typedef strategy::transform::copy_per_coordinate<P1, P2> type;
+};
+
+/// Specialization to convert from degree to radian for any coordinate system / point type combination
+template <typename CoordSysTag, template<typename> class CoordSys, typename P1, typename P2>
+struct strategy_transform<CoordSysTag, CoordSysTag, CoordSys<degree>, CoordSys<radian>, 2, 2, P1, P2>
+{
+    typedef strategy::transform::degree_radian_vv<P1, P2, std::multiplies> type;
+};
+
+/// Specialization to convert from radian to degree for any coordinate system / point type combination
+template <typename CoordSysTag, template<typename> class CoordSys, typename P1, typename P2>
+struct strategy_transform<CoordSysTag, CoordSysTag, CoordSys<radian>, CoordSys<degree>, 2, 2, P1, P2>
+{
+    typedef strategy::transform::degree_radian_vv<P1, P2, std::divides> type;
+};
+
+
+/// Specialization degree->radian in 3D
+template <typename CoordSysTag, template<typename> class CoordSys, typename P1, typename P2>
+struct strategy_transform<CoordSysTag, CoordSysTag, CoordSys<degree>, CoordSys<radian>, 3, 3, P1, P2>
+{
+    typedef strategy::transform::degree_radian_vv_3<P1, P2, std::multiplies> type;
+};
+
+/// Specialization radian->degree in 3D
+template <typename CoordSysTag, template<typename> class CoordSys, typename P1, typename P2>
+struct strategy_transform<CoordSysTag, CoordSysTag, CoordSys<radian>, CoordSys<degree>, 3, 3, P1, P2>
+{
+    typedef strategy::transform::degree_radian_vv_3<P1, P2, std::divides> type;
+};
+
+/// Specialization to convert from unit sphere(phi,theta) to XYZ
+template <typename CoordSys1, typename CoordSys2, typename P1, typename P2>
+struct strategy_transform<spherical_tag, cartesian_tag, CoordSys1, CoordSys2, 2, 3, P1, P2>
+{
+    typedef strategy::transform::from_spherical_2_to_cartesian_3<P1, P2> type;
+};
+
+/// Specialization to convert from sphere(phi,theta,r) to XYZ
+template <typename CoordSys1, typename CoordSys2, typename P1, typename P2>
+struct strategy_transform<spherical_tag, cartesian_tag, CoordSys1, CoordSys2, 3, 3, P1, P2>
+{
+    typedef strategy::transform::from_spherical_3_to_cartesian_3<P1, P2> type;
+};
+
+/// Specialization to convert from XYZ to unit sphere(phi,theta)
+template <typename CoordSys1, typename CoordSys2, typename P1, typename P2>
+struct strategy_transform<cartesian_tag, spherical_tag, CoordSys1, CoordSys2, 3, 2, P1, P2>
+{
+    typedef strategy::transform::from_cartesian_3_to_spherical_2<P1, P2> type;
+};
+
+/// Specialization to convert from XYZ to sphere(phi,theta,r)
+template <typename CoordSys1, typename CoordSys2, typename P1, typename P2>
+struct strategy_transform<cartesian_tag, spherical_tag, CoordSys1, CoordSys2, 3, 3, P1, P2>
+{
+    typedef strategy::transform::from_cartesian_3_to_spherical_3<P1, P2> type;
+};
+
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+} // namespace ggl
+
+#endif // GGL_STRATEGIES_STRATEGY_TRANSFORM_HPP
Added: sandbox/ggl/formal_review/boost/ggl/strategies/tags.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/strategies/tags.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,44 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGIES_TAGS_HPP
+#define GGL_STRATEGIES_TAGS_HPP
+
+
+namespace ggl
+{
+
+namespace strategy
+{
+    /*!
+        \brief Indicate compiler/library user that strategy is not implemented.
+        \details Strategies are defined for point types or for point type
+        combinations. If there is no implementation for that specific point type, or point type
+        combination, the calculation cannot be done. To indicate this, this not_implemented
+        class is used as a typedef stub.
+
+    */
+    struct not_implemented {};
+}
+
+
+
+
+struct strategy_tag_unknown {};
+struct strategy_tag_distance_point_point {};
+struct strategy_tag_distance_point_segment {};
+
+template <typename T>
+struct strategy_tag
+{
+    typedef strategy_tag_unknown type;
+};
+
+} // namespace ggl
+
+#endif // GGL_STRATEGIES_TAGS_HPP
Added: sandbox/ggl/formal_review/boost/ggl/strategies/transform.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/strategies/transform.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,50 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGIES_TRANSFORM_HPP
+#define GGL_STRATEGIES_TRANSFORM_HPP
+
+#include <cstddef>
+
+#include <ggl/strategies/tags.hpp>
+
+
+namespace ggl
+{
+
+
+/*!
+    \brief Traits class binding a transformation strategy to a coordinate system
+    \ingroup transform
+    \details Can be specialized
+    - per coordinate system family (tag)
+    - per coordinate system (or groups of them)
+    - per dimension
+    - per point type
+    \tparam CoordinateSystemTag 1,2 coordinate system tags
+    \tparam CoordinateSystem 1,2 coordinate system
+    \tparam D 1, 2 dimension
+    \tparam Point 1, 2 point type
+ */
+template
+<
+    typename CoordinateSystemTag1, typename CoordinateSystemTag2,
+    typename CoordinateSystem1, typename CoordinateSystem2,
+    std::size_t Dimension1, std::size_t Dimension2,
+    typename Point1, typename Point2
+>
+struct strategy_transform
+{
+    typedef strategy::not_implemented type;
+};
+
+
+
+} // namespace ggl
+
+#endif // GGL_STRATEGIES_TRANSFORM_HPP
Added: sandbox/ggl/formal_review/boost/ggl/strategies/transform/inverse_transformer.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/strategies/transform/inverse_transformer.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,70 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGIES_TRANSFORM_INVERSE_TRANSFORMER_HPP
+#define GGL_STRATEGIES_TRANSFORM_INVERSE_TRANSFORMER_HPP
+
+// Remove the ublas checking, otherwise the inverse might fail 
+// (while nothing seems to be wrong)
+#define BOOST_UBLAS_TYPE_CHECK 0
+
+#include <boost/numeric/ublas/lu.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+#include <ggl/strategies/transform/matrix_transformers.hpp>
+
+namespace ggl
+{
+
+namespace strategy { namespace transform {
+
+/*!
+    \brief Transformation strategy to do an inverse ransformation in Cartesian system
+    \ingroup transform
+    \tparam P1 first point type
+    \tparam P2 second point type
+ */
+template <typename P1, typename P2>
+struct inverse_transformer 
+    : ublas_transformer<P1, P2, dimension<P1>::type::value, dimension<P2>::type::value>
+{
+    typedef typename select_coordinate_type<P1, P2>::type T;
+
+    template <typename MatrixType>
+    inline inverse_transformer(const MatrixType& input)
+    {
+        typedef boost::numeric::ublas::matrix<double> matrix_type;
+        // create a working copy of the input
+        matrix_type copy(input.matrix());
+
+        // create a permutation matrix for the LU-factorization
+        typedef boost::numeric::ublas::permutation_matrix<> permutation_matrix;
+        permutation_matrix pm(copy.size1());
+
+        // perform LU-factorization
+        int res = boost::numeric::ublas::lu_factorize<matrix_type>(copy, pm);
+        if( res == 0 )
+        {
+            // create identity matrix
+            this->m_matrix.assign(boost::numeric::ublas::identity_matrix<T>(copy.size1()));
+
+            // backsubstitute to get the inverse
+            boost::numeric::ublas::lu_substitute(copy, pm, this->m_matrix);
+        }
+    }
+
+
+};
+
+
+}} // namespace strategy::transform
+
+
+} // namespace ggl
+
+#endif // GGL_STRATEGIES_TRANSFORM_INVERSE_TRANSFORMER_HPP
Added: sandbox/ggl/formal_review/boost/ggl/strategies/transform/map_transformer.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/strategies/transform/map_transformer.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,145 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGIES_TRANSFORM_MAP_TRANSFORMER_HPP
+#define GGL_STRATEGIES_TRANSFORM_MAP_TRANSFORMER_HPP
+
+
+#include <ggl/strategies/transform/matrix_transformers.hpp>
+
+
+namespace ggl
+{
+
+namespace strategy { namespace transform {
+
+/*!
+    \brief Transformation strategy to do map from one to another Cartesian system
+    \ingroup transform
+    \tparam P1 first point type
+    \tparam P2 second point type
+    \tparam Mirror if true map is mirrored upside-down (in most cases pixels
+        are from top to bottom, while map is from bottom to top)
+ */
+template 
+<
+    typename P1, typename P2, 
+    bool Mirror, bool SameScale = true,
+    std::size_t Dimension1 = dimension<P1>::type::value,
+    std::size_t Dimension2 = dimension<P2>::type::value
+>
+struct map_transformer 
+    : ublas_transformer<P1, P2, Dimension1, Dimension2>
+{
+    typedef typename select_coordinate_type<P1, P2>::type T;
+    typedef boost::numeric::ublas::matrix<T> M;
+
+    template <typename B, typename D>
+    explicit inline map_transformer(B const& box, D const& width, D const& height)
+    {
+        set_transformation(
+                get<min_corner, 0>(box), get<min_corner, 1>(box),
+                get<max_corner, 0>(box), get<max_corner, 1>(box),
+                width, height);
+    }
+
+    template <typename W, typename D>
+    explicit inline map_transformer(W const& wx1, W const& wy1, W const& wx2, W const& wy2,
+                        D const& width, D const& height)
+    {
+        set_transformation(wx1, wy1, wx2, wy2, width, height);
+    }
+
+
+    private :
+        void set_transformation_point(double wx, double wy, double px, double py, double scalex, double scaley)
+        {
+
+            // Translate to a coordinate system centered on world coordinates (-wx, -wy)
+            M t1(3,3);
+            t1(0,0) = 1;   t1(0,1) = 0;   t1(0,2) = -wx;
+            t1(1,0) = 0;   t1(1,1) = 1;   t1(1,2) = -wy;
+            t1(2,0) = 0;   t1(2,1) = 0;   t1(2,2) = 1;
+
+            // Scale the map
+            M s(3,3);
+            s(0,0) = scalex;   s(0,1) = 0;   s(0,2) = 0;
+            s(1,0) = 0;    s(1,1) = scaley;  s(1,2) = 0;
+            s(2,0) = 0;    s(2,1) = 0;      s(2,2) = 1;
+
+            // Translate to a coordinate system centered on the specified pixels (+px, +py)
+            M t2(3, 3);
+            t2(0,0) = 1;   t2(0,1) = 0;   t2(0,2) = px;
+            t2(1,0) = 0;   t2(1,1) = 1;   t2(1,2) = py;
+            t2(2,0) = 0;   t2(2,1) = 0;   t2(2,2) = 1;
+
+            // Calculate combination matrix in two steps
+            this->m_matrix = boost::numeric::ublas::prod(s, t1);
+            this->m_matrix = boost::numeric::ublas::prod(t2, this->m_matrix);
+        }
+
+
+        template <typename W, typename D>
+        void set_transformation(W const& wx1, W const& wy1, W const& wx2, W const& wy2,
+                        D const& width, D const& height)
+        {
+            D px1 = 0;
+            D py1 = 0;
+            D px2 = width;
+            D py2 = height;
+
+
+            // Calculate appropriate scale, take min because whole box must fit
+            // Scale is in PIXELS/MAPUNITS (meters)
+            double sx = (px2 - px1) / (wx2 - wx1);
+            double sy = (py2 - py1) / (wy2 - wy1);
+
+            if (SameScale)
+            {
+                double scale = (std::min)(sx, sy);
+                sx = scale;
+                sy = scale;
+            }
+
+            // Calculate centerpoints
+            double wmx = (wx1 + wx2) / 2.0;
+            double wmy = (wy1 + wy2) / 2.0;
+            double pmx = (px1 + px2) / 2.0;
+            double pmy = (py1 + py2) / 2.0;
+
+            set_transformation_point(wmx, wmy, pmx, pmy, sx, sy);
+
+            if (Mirror)
+            {
+                // Mirror in y-direction
+                M m(3,3);
+                m(0,0) = 1;   m(0,1) = 0;   m(0,2) = 0;
+                m(1,0) = 0;   m(1,1) = -1;  m(1,2) = 0;
+                m(2,0) = 0;   m(2,1) = 0;   m(2,2) = 1;
+
+                // Translate in y-direction such that it fits again
+                M y(3, 3);
+                y(0,0) = 1;   y(0,1) = 0;   y(0,2) = 0;
+                y(1,0) = 0;   y(1,1) = 1;   y(1,2) = height;
+                y(2,0) = 0;   y(2,1) = 0;   y(2,2) = 1;
+
+                // Calculate combination matrix in two steps
+                this->m_matrix = boost::numeric::ublas::prod(m, this->m_matrix);
+                this->m_matrix = boost::numeric::ublas::prod(y, this->m_matrix);
+            }
+        }
+};
+
+}} // namespace strategy::transform
+
+
+
+} // namespace ggl
+
+
+#endif // GGL_STRATEGIES_TRANSFORM_MAP_TRANSFORMER_HPP
Added: sandbox/ggl/formal_review/boost/ggl/strategies/transform/matrix_transformers.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/strategies/transform/matrix_transformers.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,362 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_STRATEGIES_TRANSFORM_MATRIX_TRANSFORMERS_HPP
+#define GGL_STRATEGIES_TRANSFORM_MATRIX_TRANSFORMERS_HPP
+
+
+// Remove the ublas checking, otherwise the inverse might fail
+// (while nothing seems to be wrong)
+#define BOOST_UBLAS_TYPE_CHECK 0
+
+#include <boost/numeric/conversion/cast.hpp>
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/matrix.hpp>
+
+#include <ggl/core/access.hpp>
+#include <ggl/core/coordinate_dimension.hpp>
+#include <ggl/core/cs.hpp>
+#include <ggl/util/math.hpp>
+#include <ggl/util/select_coordinate_type.hpp>
+
+
+namespace ggl
+{
+
+
+namespace strategy { namespace transform {
+
+
+/*!
+    \brief Transformation strategy to do an affine matrix transformation in Cartesian system
+    \ingroup transform
+    \tparam P1 first point type
+    \tparam P2 second point type
+    \tparam Dimension1 number of dimensions to transform from first point, optional
+    \tparam Dimension1 number of dimensions to transform to second point, optional
+ */
+template
+<
+    typename P1, typename P2,
+    std::size_t Dimension1,
+    std::size_t Dimension2
+>
+class ublas_transformer
+{
+};
+
+template <typename P1, typename P2>
+class ublas_transformer<P1, P2, 2, 2>
+{
+protected :
+    typedef typename select_coordinate_type<P1, P2>::type coordinate_type;
+    typedef coordinate_type ct; // Abbreviation
+    typedef boost::numeric::ublas::matrix<coordinate_type> matrix_type;
+    matrix_type m_matrix;
+
+public :
+    inline ublas_transformer(
+                ct const& m_0_0, ct const& m_0_1, ct const& m_0_2,
+                ct const& m_1_0, ct const& m_1_1, ct const& m_1_2,
+                ct const& m_2_0, ct const& m_2_1, ct const& m_2_2)
+        : m_matrix(3, 3)
+    {
+        m_matrix(0,0) = m_0_0;   m_matrix(0,1) = m_0_1;   m_matrix(0,2) = m_0_2;
+        m_matrix(1,0) = m_1_0;   m_matrix(1,1) = m_1_1;   m_matrix(1,2) = m_1_2;
+        m_matrix(2,0) = m_2_0;   m_matrix(2,1) = m_2_1;   m_matrix(2,2) = m_2_2;
+    }
+
+    inline ublas_transformer()
+        : m_matrix(3, 3)
+    {
+    }
+
+
+    inline bool operator()(const P1& p1, P2& p2) const
+    {
+        assert_dimension_greater_equal<P1, 2>();
+        assert_dimension_greater_equal<P2, 2>();
+
+        const coordinate_type& c1 = get<0>(p1);
+        const coordinate_type& c2 = get<1>(p1);
+
+        typedef typename ggl::coordinate_type<P2>::type ct2;
+
+        set<0>(p2, boost::numeric_cast<ct2>(c1 * m_matrix(0,0)
+                + c2 * m_matrix(0,1) + m_matrix(0,2)));
+        set<1>(p2, boost::numeric_cast<ct2>(c1 * m_matrix(1,0)
+                + c2 * m_matrix(1,1) + m_matrix(1,2)));
+
+        return true;
+    }
+
+    const matrix_type& matrix() const { return m_matrix; }
+};
+
+// It IS possible to go from 3 to 2 coordinates
+template <typename P1, typename P2>
+struct ublas_transformer<P1, P2, 3, 2>
+    : public ublas_transformer<P1, P2, 2, 2>
+{
+    typedef typename select_coordinate_type<P1, P2>::type coordinate_type;
+    typedef coordinate_type ct; // Abbreviation
+
+    inline ublas_transformer(
+                ct const& m_0_0, ct const& m_0_1, ct const& m_0_2,
+                ct const& m_1_0, ct const& m_1_1, ct const& m_1_2,
+                ct const& m_2_0, ct const& m_2_1, ct const& m_2_2)
+        : ublas_transformer<P1, P2, 2, 2>(
+                    m_0_0, m_0_1, m_0_2,
+                    m_1_0, m_1_1, m_1_2,
+                    m_2_0, m_2_1, m_2_2)
+    {}
+
+    inline ublas_transformer()
+        : ublas_transformer<P1, P2, 2, 2>()
+    {}
+};
+
+
+template <typename P1, typename P2>
+class ublas_transformer<P1, P2, 3, 3>
+{
+protected :
+    typedef typename select_coordinate_type<P1, P2>::type coordinate_type;
+    typedef coordinate_type ct; // Abbreviation
+    typedef boost::numeric::ublas::matrix<coordinate_type> matrix_type;
+    matrix_type m_matrix;
+
+    inline ublas_transformer(
+                ct const& m_0_0, ct const& m_0_1, ct const& m_0_2, ct const& m_0_3,
+                ct const& m_1_0, ct const& m_1_1, ct const& m_1_2, ct const& m_1_3,
+                ct const& m_2_0, ct const& m_2_1, ct const& m_2_2, ct const& m_2_3,
+                ct const& m_3_0, ct const& m_3_1, ct const& m_3_2, ct const& m_3_3
+                )
+        : m_matrix(4, 4)
+    {
+        m_matrix(0,0) = m_0_0; m_matrix(0,1) = m_0_1; m_matrix(0,2) = m_0_2; m_matrix(0,3) = m_0_3;
+        m_matrix(1,0) = m_1_0; m_matrix(1,1) = m_1_1; m_matrix(1,2) = m_1_2; m_matrix(1,3) = m_1_3;
+        m_matrix(2,0) = m_2_0; m_matrix(2,1) = m_2_1; m_matrix(2,2) = m_2_2; m_matrix(2,3) = m_2_3;
+        m_matrix(3,0) = m_3_0; m_matrix(3,1) = m_3_1; m_matrix(3,2) = m_3_2; m_matrix(3,3) = m_3_3;
+    }
+
+    inline ublas_transformer()
+        : m_matrix(4, 4)
+    {
+    }
+
+
+public :
+
+    inline bool operator()(const P1& p1, P2& p2) const
+    {
+        const coordinate_type& c1 = get<0>(p1);
+        const coordinate_type& c2 = get<1>(p1);
+        const coordinate_type& c3 = get<2>(p1);
+
+        typedef typename ggl::coordinate_type<P2>::type ct2;
+
+        set<0>(p2, boost::numeric_cast<ct2>(c1 * m_matrix(0,0)
+                + c2 * m_matrix(0,1) + c3 * m_matrix(0,2) + m_matrix(0,3)));
+        set<1>(p2, boost::numeric_cast<ct2>(c1 * m_matrix(1,0)
+                + c2 * m_matrix(1,1) + c3 * m_matrix(1,2) + m_matrix(1,3)));
+        set<2>(p2, boost::numeric_cast<ct2>(c1 * m_matrix(2,0)
+                + c2 * m_matrix(2,1) + c3 * m_matrix(2,2) + m_matrix(2,3)));
+
+        return true;
+    }
+
+    const matrix_type& matrix() const { return m_matrix; }
+};
+
+
+
+
+/*!
+    \brief Transformation strategy to translate in Cartesian system
+    \ingroup transform
+    \see http://www.devmaster.net/wiki/Transformation_matrices
+    \tparam P1 first point type
+    \tparam P2 second point type
+    \tparam Dimension1 number of dimensions to transform from first point, optional
+    \tparam Dimension1 number of dimensions to transform to second point, optional
+ */
+template
+<
+    typename P1, typename P2,
+    std::size_t Dimension1 = ggl::dimension<P1>::type::value,
+    std::size_t Dimension2 = ggl::dimension<P2>::type::value
+>
+struct translate_transformer {};
+
+
+template <typename P1, typename P2>
+struct translate_transformer<P1, P2, 2, 2>
+        : ublas_transformer<P1, P2, 2, 2>
+{
+    typedef typename select_coordinate_type<P1, P2>::type coordinate_type;
+
+    // To have translate transformers compatible for 2/3 dimensions, the
+    // constructor takes an optional third argument doing nothing.
+    inline translate_transformer(coordinate_type const& translate_x,
+                coordinate_type const& translate_y,
+                coordinate_type const& dummy = 0)
+        : ublas_transformer<P1, P2, 2, 2>(
+                1, 0, translate_x,
+                0, 1, translate_y,
+                0, 0, 1)
+    {}
+
+};
+
+template <typename P1, typename P2>
+struct translate_transformer<P1, P2, 3, 3> : ublas_transformer<P1, P2, 3, 3>
+{
+    typedef typename select_coordinate_type<P1, P2>::type coordinate_type;
+
+    inline translate_transformer(coordinate_type const& translate_x,
+                coordinate_type const& translate_y,
+                coordinate_type const& translate_z)
+        : ublas_transformer<P1, P2, 3, 3>(
+                1, 0, 0, translate_x,
+                0, 1, 0, translate_y,
+                0, 0, 1, translate_z,
+                0, 0, 0, 1)
+    {}
+
+};
+
+
+/*!
+    \brief Transformation strategy to scale in Cartesian system
+    \ingroup transform
+    \see http://www.devmaster.net/wiki/Transformation_matrices
+    \tparam P1 first point type
+    \tparam P2 second point type
+    \tparam Dimension1 number of dimensions to transform from first point, optional
+    \tparam Dimension1 number of dimensions to transform to second point, optional
+*/
+template
+<
+    typename P1, typename P2,
+    std::size_t Dimension1 = ggl::dimension<P1>::type::value,
+    std::size_t Dimension2 = ggl::dimension<P2>::type::value
+>
+struct scale_transformer {};
+
+
+template <typename P1, typename P2>
+struct scale_transformer<P1, P2, 2, 2> : ublas_transformer<P1, P2, 2, 2>
+{
+    typedef typename select_coordinate_type<P1, P2>::type coordinate_type;
+
+    inline scale_transformer(coordinate_type const& scale_x,
+                coordinate_type const& scale_y,
+                coordinate_type const& dummy = 0)
+        : ublas_transformer<P1, P2, 2, 2>(
+                scale_x, 0,       0,
+                0,       scale_y, 0,
+                0,       0,       1)
+    {}
+};
+
+
+template <typename P1, typename P2>
+struct scale_transformer<P1, P2, 3, 3> : ublas_transformer<P1, P2, 3, 3>
+{
+    typedef typename select_coordinate_type<P1, P2>::type coordinate_type;
+
+    inline scale_transformer(coordinate_type const& scale_x,
+                coordinate_type const& scale_y,
+                coordinate_type const& scale_z)
+        : ublas_transformer<P1, P2, 3, 3>(
+                scale_x, 0,       0,       0,
+                0,       scale_y, 0,       0,
+                0,       0,       scale_z, 0,
+                0,       0,       0,       1)
+    {}
+};
+
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail {
+
+template <typename DegreeOrRadian>
+struct as_radian {};
+
+template <>
+struct as_radian<radian>
+{
+    static inline double get(double const& value)
+    {
+        return value;
+    }
+};
+
+template <>
+struct as_radian<degree>
+{
+    static inline double get(double const& value)
+    {
+        return value * math::d2r;
+    }
+
+};
+
+
+template
+<
+    typename P1, typename P2,
+    std::size_t Dimension1 = ggl::dimension<P1>::type::value,
+    std::size_t Dimension2 = ggl::dimension<P2>::type::value
+>
+struct rad_rotate_transformer
+    : ublas_transformer<P1, P2, Dimension1, Dimension2>
+{
+    inline rad_rotate_transformer(double const& angle)
+        : ublas_transformer<P1, P2, Dimension1, Dimension2>(
+                 cos(angle), sin(angle), 0,
+                -sin(angle), cos(angle), 0,
+                 0,          0,          1)
+    {}
+};
+
+}
+#endif
+
+
+/*!
+    \brief Transformation strategy to rotate in Cartesian system
+    \ingroup transform
+    \tparam P1 first point type
+    \tparam P2 second point type
+    \tparam DegreeOrRadian degree/or/radian, type of rotation angle specification
+    \note Not yet in 3D, the 3D version requires special things to allow for
+      rotation around X, Y, Z or arbitrary axis
+    \see http://www.devmaster.net/wiki/Transformation_matrices
+    \note The 3D version will not compile
+ */
+template <typename P1, typename P2, typename DegreeOrRadian>
+struct rotate_transformer : detail::rad_rotate_transformer<P1, P2>
+{
+    inline rotate_transformer(double const& angle)
+        : detail::rad_rotate_transformer
+            <
+                P1, P2
+            >(detail::as_radian<DegreeOrRadian>::get(angle))
+    {}
+
+};
+
+
+}} // namespace strategy::transform
+
+} // namespace ggl
+
+#endif // GGL_STRATEGIES_TRANSFORM_MATRIX_TRANSFORMERS_HPP
Added: sandbox/ggl/formal_review/boost/ggl/util/add_const_if_c.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/util/add_const_if_c.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,50 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_UTIL_ADD_CONST_IF_C_HPP
+#define GGL_UTIL_ADD_CONST_IF_C_HPP
+
+
+#include <boost/mpl/if.hpp>
+
+
+namespace ggl
+{
+
+
+/*!
+    \brief Meta-function to define a const or non const type
+    \ingroup utility
+    \details If the boolean template parameter is true, the type parameter
+        will be defined as const, otherwise it will be defined as it was.
+        This meta-function is used to have one implementation for both
+        const and non const references
+    \note This traits class is completely independant from GGL and might be a
+        separate addition to Boost
+    \note Used in ggl::for_each
+    \par Example
+    \code
+        void foo(typename add_const_if_c<IsConst, Point>::type& point)
+    \endcode
+*/
+template <bool IsConst, typename Type>
+struct add_const_if_c
+{
+    typedef typename boost::mpl::if_c
+        <
+            IsConst,
+            const Type,
+            Type
+        >::type type;
+};
+
+
+
+} // namespace ggl
+
+
+#endif // GGL_UTIL_ADD_CONST_IF_C_HPP
Added: sandbox/ggl/formal_review/boost/ggl/util/as_range.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/util/as_range.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,98 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_UTIL_AS_RANGE_HPP
+#define GGL_UTIL_AS_RANGE_HPP
+
+#include <boost/type_traits.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+#include <ggl/core/exterior_ring.hpp>
+#include <ggl/core/is_multi.hpp>
+#include <ggl/core/tag.hpp>
+#include <ggl/core/tags.hpp>
+
+#include <ggl/util/add_const_if_c.hpp>
+
+
+namespace ggl {
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template <typename GeometryTag, typename Geometry, typename Range, bool IsConst>
+struct as_range
+{
+    static inline typename add_const_if_c<IsConst, Range>::type& get(
+            typename add_const_if_c<IsConst, Geometry>::type& input)
+    {
+        return input;
+    }
+};
+
+
+template <typename Geometry, typename Range, bool IsConst>
+struct as_range<polygon_tag, Geometry, Range, IsConst>
+{
+    static inline typename add_const_if_c<IsConst, Range>::type& get(
+            typename add_const_if_c<IsConst, Geometry>::type& input)
+    {
+        return exterior_ring(input);
+    }
+};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+\brief Function getting either the range (ring, linestring) itself
+or the outer ring (polygon)
+\details Utility to handle polygon's outer ring as a range
+\ingroup utility
+*/
+template <typename Range, typename Geometry>
+inline Range& as_range(Geometry& input)
+{
+    return dispatch::as_range
+        <
+            typename tag<Geometry>::type,
+            Geometry,
+            Range,
+            false
+        >::get(input);
+}
+
+
+/*!
+\brief Function getting either the range (ring, linestring) itself
+or the outer ring (polygon), const version
+\details Utility to handle polygon's outer ring as a range
+\ingroup utility
+*/
+template <typename Range, typename Geometry>
+inline Range const& as_range(Geometry const& input)
+{
+    return dispatch::as_range
+        <
+            typename tag<Geometry>::type,
+            Geometry,
+            Range,
+            true
+        >::get(input);
+}
+
+
+} // namespace ggl
+
+
+#endif // GGL_UTIL_AS_RANGE_HPP
Added: sandbox/ggl/formal_review/boost/ggl/util/copy.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/util/copy.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,80 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_UTIL_COPY_HPP
+#define GGL_UTIL_COPY_HPP
+
+#include <cstddef>
+
+#include <boost/concept/requires.hpp>
+#include <boost/concept_check.hpp>
+
+#include <ggl/geometries/concepts/point_concept.hpp>
+
+#include <boost/numeric/conversion/cast.hpp>
+
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace copy {
+
+template <typename Src, typename Dst, std::size_t D, std::size_t N>
+struct copy_coordinates
+{
+    static inline void copy(Src const& source, Dst& dest)
+    {
+        typedef typename coordinate_type<Dst>::type coordinate_type;
+
+        set<D>(dest, boost::numeric_cast<coordinate_type>(get<D>(source)));
+        copy_coordinates<Src, Dst, D + 1, N>::copy(source, dest);
+    }
+};
+
+template <typename Src, typename Dst, std::size_t N>
+struct copy_coordinates<Src, Dst, N, N>
+{
+    static inline void copy(Src const& , Dst& )
+    {
+    }
+};
+
+}} // namespace detail::copy
+#endif // DOXYGEN_NO_DETAIL
+
+
+/*!
+    \brief Copies coordinates from source to destination point
+    \ingroup assign
+    \details The function copy_coordinates copies coordinates from one point to another point.
+    Source point and destination point might be of different types.
+    \param source Source point
+    \param dest Destination point
+    \note If destination type differs from source type, they must have the same coordinate count
+ */
+template <typename Src, typename Dst>
+inline void copy_coordinates(Src const& source, Dst& dest)
+{
+    BOOST_CONCEPT_ASSERT( (concept::ConstPoint<Src>) );
+    BOOST_CONCEPT_ASSERT( (concept::Point<Dst>) );
+
+
+    //assert_dimension_equal<Dst, Src>();
+    detail::copy::copy_coordinates
+        <
+            Src,
+            Dst,
+            0,
+            dimension<Src>::type::value
+        >::copy(source, dest);
+}
+
+} // namespace ggl
+
+#endif // GGL_UTIL_COPY_HPP
Added: sandbox/ggl/formal_review/boost/ggl/util/for_each_coordinate.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/util/for_each_coordinate.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,64 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_UTIL_FOR_EACH_COORDINATE_HPP
+#define GGL_UTIL_FOR_EACH_COORDINATE_HPP
+
+#include <boost/concept/requires.hpp>
+#include <ggl/geometries/concepts/point_concept.hpp>
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail
+{
+
+template <typename Point, int Dimension, int DimensionCount>
+struct coordinates_scanner
+{
+    template <typename Op>
+    static inline void apply(Point& point, Op operation)
+    {
+        operation.template apply<Point, Dimension>(point);
+        coordinates_scanner
+            <
+                Point,
+                Dimension+1,
+                DimensionCount
+            >::apply(point, operation);
+    }
+};
+
+template <typename Point, int DimensionCount>
+struct coordinates_scanner<Point, DimensionCount, DimensionCount>
+{
+    template <typename Op>
+    static inline void apply(Point&, Op)
+    {}
+};
+
+} // namespace detail
+#endif // DOXYGEN_NO_DETAIL
+
+template <typename Point, typename Op>
+inline void for_each_coordinate(Point& point, Op operation)
+{
+    BOOST_CONCEPT_ASSERT( (concept::Point<Point>) );
+
+    typedef typename detail::coordinates_scanner
+        <
+            Point, 0, dimension<Point>::type::value
+        > scanner;
+
+    scanner::apply(point, operation);
+}
+
+} // namespace ggl
+
+#endif // GGL_UTIL_FOR_EACH_COORDINATE_HPP
Added: sandbox/ggl/formal_review/boost/ggl/util/for_each_range.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/util/for_each_range.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,116 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_UTIL_FOR_EACH_RANGE_HPP
+#define GGL_UTIL_FOR_EACH_RANGE_HPP
+
+
+#include <boost/concept/requires.hpp>
+
+
+#include <ggl/core/tag.hpp>
+#include <ggl/core/is_multi.hpp>
+
+#include <ggl/util/add_const_if_c.hpp>
+
+
+namespace ggl
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace for_each {
+
+
+template <typename Range, typename Actor, bool IsConst>
+struct fe_range_range
+{
+    static inline void apply(
+                    typename add_const_if_c<IsConst, Range>::type& range,
+                    Actor& actor)
+    {
+        actor.apply(range);
+    }
+};
+
+
+template <typename Polygon, typename Actor, bool IsConst>
+struct fe_range_polygon
+{
+    static inline void apply(
+                    typename add_const_if_c<IsConst, Polygon>::type& polygon,
+                    Actor& actor)
+    {
+        actor.apply(exterior_ring(polygon));
+
+        // TODO: If some flag says true, also do the inner rings.
+        // for convex hull, it's not necessary
+    }
+};
+
+
+}} // namespace detail::for_each
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+
+template
+<
+    typename Tag,
+    bool IsMulti,
+    typename Geometry,
+    typename Actor,
+    bool IsConst
+>
+struct for_each_range {};
+
+
+template <typename Linestring, typename Actor, bool IsConst>
+struct for_each_range<linestring_tag, false, Linestring, Actor, IsConst>
+    : detail::for_each::fe_range_range<Linestring, Actor, IsConst>
+{};
+
+
+template <typename Ring, typename Actor, bool IsConst>
+struct for_each_range<ring_tag, false, Ring, Actor, IsConst>
+    : detail::for_each::fe_range_range<Ring, Actor, IsConst>
+{};
+
+
+template <typename Polygon, typename Actor, bool IsConst>
+struct for_each_range<polygon_tag, false, Polygon, Actor, IsConst>
+    : detail::for_each::fe_range_polygon<Polygon, Actor, IsConst>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+template <typename Geometry, typename Actor>
+inline void for_each_range(Geometry const& geometry, Actor& actor)
+{
+    dispatch::for_each_range
+        <
+            typename tag<Geometry>::type,
+            is_multi<Geometry>::type::value,
+            Geometry,
+            Actor,
+            true
+        >::apply(geometry, actor);
+}
+
+
+} // namespace ggl
+
+
+#endif // GGL_UTIL_FOR_EACH_RANGE_HPP
Added: sandbox/ggl/formal_review/boost/ggl/util/math.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/util/math.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,119 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_UTIL_MATH_HPP
+#define GGL_UTIL_MATH_HPP
+
+#include <cmath>
+#include <limits>
+
+#include <boost/math/constants/constants.hpp>
+
+#include <ggl/util/select_most_precise.hpp>
+
+namespace ggl
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace math {
+
+
+template <typename T, bool Floating>
+struct equals
+{
+    static inline bool apply(T const& a, T const& b)
+    {
+        return a == b;
+    }
+};
+
+template <typename T>
+struct equals<T, true>
+{
+    static inline bool apply(T const& a, T const& b)
+    {
+        // See http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.17,
+        // FUTURE: replace by some boost tool or boost::test::close_at_tolerance
+        return std::abs(a - b) <= std::numeric_limits<T>::epsilon() * std::abs(a);
+    }
+};
+
+
+}} // namespace detail::math
+#endif
+
+namespace math
+{
+
+
+// Maybe replace this by boost equals or boost ublas numeric equals or so
+
+/*!
+    \brief returns true if both arguments are equal.
+    \ingroup utility
+    \param a first argument
+    \param b second argument
+    \return true if a == b
+    \note If both a and b are of an integral type, comparison is done by ==.
+    If one of the types is floating point, comparison is done by abs and
+    comparing with epsilon. If one of the types is non-fundamental, it might
+    be a high-precision number and comparison is done using the == operator
+    of that class.
+*/
+
+template <typename T1, typename T2>
+inline bool equals(T1 const& a, T2 const& b)
+{
+    typedef typename select_most_precise<T1, T2>::type select_type;
+    return detail::math::equals
+        <
+            select_type,
+            boost::is_floating_point<select_type>::type::value
+        >::apply(a, b);
+}
+
+
+
+double const pi = boost::math::constants::pi<double>();
+double const two_pi = 2.0 * pi;
+double const d2r = pi / 180.0;
+double const r2d = 1.0 / d2r;
+
+/*!
+    \brief Calculates the haversine of an angle
+    \ingroup utility
+    \note See http://en.wikipedia.org/wiki/Haversine_formula
+    haversin(alpha) = sin2(alpha/2)
+*/
+template <typename T>
+inline T hav(T const& theta)
+{
+    using boost::math::constants::half;
+    T const sn = std::sin(half<T>() * theta);
+    return sn * sn;
+}
+
+/*!
+\brief Short utility to return the square
+\ingroup utility
+\param value Value to calculate the square from
+\return The squared value
+*/
+template <typename T>
+inline T sqr(T const& value)
+{
+    return value * value;
+}
+
+} // namespace math
+
+
+} // namespace ggl
+
+#endif // GGL_UTIL_MATH_HPP
Added: sandbox/ggl/formal_review/boost/ggl/util/range_iterator_const_if_c.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/util/range_iterator_const_if_c.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,45 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_UTIL_RANGE_ITERATOR_CONST_IF_C_HPP
+#define GGL_UTIL_RANGE_ITERATOR_CONST_IF_C_HPP
+
+
+#include <boost/mpl/if.hpp>
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+
+namespace ggl
+{
+
+
+/*!
+    \brief Meta-function to define a const or non const boost range iterator
+    \ingroup utility
+    \details Is used to have one implementation for both const and non const
+        range iterators
+    \note This traits class is completely independant from GGL and might be a
+        separate addition to Boost
+    \note Used in ggl::for_each
+*/
+template <bool IsConst, typename Range>
+struct range_iterator_const_if_c
+{
+    typedef typename boost::mpl::if_c
+        <
+            IsConst,
+            typename boost::range_const_iterator<Range>::type,
+            typename boost::range_iterator<Range>::type
+        >::type type;
+};
+
+
+} // namespace ggl
+
+
+#endif // GGL_UTIL_RANGE_ITERATOR_CONST_IF_C_HPP
Added: sandbox/ggl/formal_review/boost/ggl/util/select_calculation_type.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/util/select_calculation_type.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,51 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 2009, Geodan, Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_UTIL_SELECT_CALCULATION_TYPE_HPP
+#define GGL_UTIL_SELECT_CALCULATION_TYPE_HPP
+
+
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits.hpp>
+
+#include <ggl/util/select_coordinate_type.hpp>
+
+
+namespace ggl
+{
+
+
+/*!
+    \brief Meta-function selecting the "calculation" type
+    \details Based on two input point types, and an input calculation type,
+        (which defaults to void in the calling function), this meta-function
+        selects the most appropriate:
+        - if calculation type is specified, that one is used,
+        - if it is void, the most precise of the two points is used
+    \ingroup utility
+ */
+template <typename Point1, typename Point2, typename CalculationType>
+struct select_calculation_type
+{
+    typedef typename
+        boost::mpl::if_c
+        <
+            boost::is_void<CalculationType>::type::value,
+            typename select_coordinate_type
+                <
+                    Point1,
+                    Point2
+                >::type,
+            CalculationType
+        >::type type;
+};
+
+
+} // namespace ggl
+
+
+#endif // GGL_UTIL_SELECT_CALCULATION_TYPE_HPP
Added: sandbox/ggl/formal_review/boost/ggl/util/select_coordinate_type.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/util/select_coordinate_type.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,44 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_UTIL_SELECT_COORDINATE_TYPE_HPP
+#define GGL_UTIL_SELECT_COORDINATE_TYPE_HPP
+
+
+#include <ggl/core/coordinate_type.hpp>
+#include <ggl/util/select_most_precise.hpp>
+
+
+/*!
+\defgroup utility utility: utility meta-functions and functions
+*/
+
+namespace ggl
+{
+
+
+/*!
+    \brief Meta-function selecting the most precise coordinate type
+        of two geometries
+    \ingroup utility
+ */
+template <typename T1, typename T2>
+struct select_coordinate_type
+{
+    typedef typename select_most_precise
+        <
+            typename coordinate_type<T1>::type,
+            typename coordinate_type<T2>::type
+        >::type type;
+};
+
+
+} // namespace ggl
+
+
+#endif // GGL_UTIL_SELECT_COORDINATE_TYPE_HPP
Added: sandbox/ggl/formal_review/boost/ggl/util/select_most_precise.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/util/select_most_precise.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,156 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Copyright Bruno Lalande 2008, 2009
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_UTIL_SELECT_MOST_PRECISE_HPP
+#define GGL_UTIL_SELECT_MOST_PRECISE_HPP
+
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits.hpp>
+
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+
+namespace detail { namespace select_most_precise {
+
+
+// At least one of the types is non-fundamental. Take that one.
+// if both are non-fundamental, the type-to-be-selected
+// is unknown, it should be defined by explicit specialization.
+template <bool Fundamental1, bool Fundamental2, typename T1, typename T2>
+struct select_non_fundamental
+{
+    typedef T1 type;
+};
+
+template <typename T1, typename T2>
+struct select_non_fundamental<true, false, T1, T2>
+{
+    typedef T2 type;
+};
+
+template <typename T1, typename T2>
+struct select_non_fundamental<false, true, T1, T2>
+{
+    typedef T1 type;
+};
+
+
+// Selection of largest type (e.g. int of <short int,int>
+// It defaults takes the first one, if second is larger, take the second one
+template <bool SecondLarger, typename T1, typename T2>
+struct select_largest
+{
+    typedef T1 type;
+};
+
+template <typename T1, typename T2>
+struct select_largest<true, T1, T2>
+{
+    typedef T2 type;
+};
+
+
+
+// Selection of floating point and specializations:
+// both FP or both !FP does never occur...
+template <bool FP1, bool FP2, typename T1, typename T2>
+struct select_floating_point
+{
+    typedef char type;
+};
+
+
+// ... so if ONE but not both of these types is floating point, take that one
+template <typename T1, typename T2>
+struct select_floating_point<true, false, T1, T2>
+{
+    typedef T1 type;
+};
+
+
+template <typename T1, typename T2>
+struct select_floating_point<false, true, T1, T2>
+{
+    typedef T2 type;
+};
+
+
+}} // namespace detail::select_most_precise
+#endif // DOXYGEN_NO_DETAIL
+
+
+/*!
+    \brief Meta-function to select, of two types, the most accurate type for
+        calculations
+    \ingroup utility
+    \details select_most_precise classes, compares two types on compile time.
+    For example, if an addition must be done with a double and an integer, the
+        result must be a double.
+    If both types are integer, the result can be an integer.
+    \note It is different from the "promote" class, already in boost. That
+        class promotes e.g. a (one) float to a double. This class selects a
+        type from two types. It takes the most accurate, but does not promote
+        afterwards.
+    \note This traits class is completely independant from GGL and might be a
+        separate addition to Boost
+    \note If the input is a non-fundamental type, it might be a calculation
+        type such as a GMP-value or another high precision value. Therefore,
+        if one is non-fundamental, that one is chosen.
+    \note If both types are non-fundamental, the result is indeterminate and
+        currently the first one is chosen.
+*/
+template <typename T1, typename T2>
+struct select_most_precise
+{
+    static const bool second_larger = sizeof(T2) > sizeof(T1);
+    static const bool one_not_fundamental = !
+        (boost::is_fundamental<T1>::type::value
+          && boost::is_fundamental<T2>::type::value);
+
+    static const bool both_same =
+        boost::is_floating_point<T1>::type::value
+        == boost::is_floating_point<T2>::type::value;
+
+    typedef typename boost::mpl::if_c
+        <
+            one_not_fundamental,
+            typename detail::select_most_precise::select_non_fundamental
+            <
+                boost::is_fundamental<T1>::type::value,
+                boost::is_fundamental<T2>::type::value,
+                T1,
+                T2
+            >::type,
+            typename boost::mpl::if_c
+            <
+                both_same,
+                typename detail::select_most_precise::select_largest
+                <
+                    second_larger,
+                    T1,
+                    T2
+                >::type,
+                typename detail::select_most_precise::select_floating_point
+                <
+                    boost::is_floating_point<T1>::type::value,
+                    boost::is_floating_point<T2>::type::value,
+                    T1,
+                    T2
+                >::type
+            >::type
+        >::type type;
+};
+
+
+
+} // namespace ggl
+
+#endif // GGL_UTIL_SELECT_MOST_PRECISE_HPP
Added: sandbox/ggl/formal_review/boost/ggl/util/write_dsv.hpp
==============================================================================
--- (empty file)
+++ sandbox/ggl/formal_review/boost/ggl/util/write_dsv.hpp	2009-11-04 12:09:58 EST (Wed, 04 Nov 2009)
@@ -0,0 +1,390 @@
+// Generic Geometry Library
+//
+// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef GGL_UTIL_WRITE_DSV_HPP
+#define GGL_UTIL_WRITE_DSV_HPP
+
+#include <iostream>
+#include <string>
+
+#include <boost/range/functions.hpp>
+#include <boost/range/metafunctions.hpp>
+
+#include <ggl/algorithms/convert.hpp>
+
+#include <ggl/core/exterior_ring.hpp>
+#include <ggl/core/interior_rings.hpp>
+#include <ggl/core/ring_type.hpp>
+#include <ggl/core/is_multi.hpp>
+
+#include <ggl/geometries/concepts/check.hpp>
+
+
+
+
+namespace ggl
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace dsv {
+
+
+struct dsv_settings
+{
+    std::string coordinate_separator;
+    std::string point_open;
+    std::string point_close;
+    std::string point_separator;
+    std::string list_open;
+    std::string list_close;
+    std::string list_separator;
+
+    dsv_settings(std::string const& sep
+            , std::string const& open
+            , std::string const& close
+            , std::string const& psep
+            , std::string const& lopen
+            , std::string const& lclose
+            , std::string const& lsep
+            )
+        : coordinate_separator(sep)
+        , point_open(open)
+        , point_close(close)
+        , point_separator(psep)
+        , list_open(lopen)
+        , list_close(lclose)
+        , list_separator(lsep)
+    {}
+};
+
+/*!
+\brief Stream coordinate of a point as \ref DSV
+*/
+template <typename Point, std::size_t Dimension, std::size_t Count>
+struct stream_coordinate
+{
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>& os,
+            Point const& point,
+            dsv_settings const& settings)
+    {
+        os << (Dimension > 0 ? settings.coordinate_separator : "")
+            << get<Dimension>(point);
+
+        stream_coordinate
+            <
+                Point, Dimension + 1, Count
+            >::apply(os, point, settings);
+    }
+};
+
+template <typename Point, std::size_t Count>
+struct stream_coordinate<Point, Count, Count>
+{
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>&,
+            Point const&,
+            dsv_settings const& settings)
+    {}
+};
+
+
+/*!
+\brief Stream indexed coordinate of a box/segment as \ref DSV
+*/
+template
+<
+    typename Geometry,
+    std::size_t Index,
+    std::size_t Dimension,
+    std::size_t Count
+>
+struct stream_indexed
+{
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>& os,
+            Geometry const& geometry,
+            dsv_settings const& settings)
+    {
+        os << (Dimension > 0 ? settings.coordinate_separator : "")
+            << get<Index, Dimension>(geometry);
+        stream_indexed
+            <
+                Geometry, Index, Dimension + 1, Count
+            >::apply(os, geometry, settings);
+    }
+};
+
+template <typename Geometry, std::size_t Index, std::size_t Count>
+struct stream_indexed<Geometry, Index, Count, Count>
+{
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>&, Geometry const&,
+            dsv_settings const& settings)
+    {}
+};
+
+
+
+
+
+/*!
+\brief Stream points as \ref DSV
+*/
+template <typename Point>
+struct dsv_point
+{
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>& os,
+            Point const& p,
+            dsv_settings const& settings)
+    {
+        os << settings.point_open;
+        stream_coordinate<Point, 0, dimension<Point>::type::value>::apply(os, p, settings);
+        os << settings.point_close;
+    }
+};
+
+/*!
+\brief Stream ranges as DSV
+\note policy is used to stream prefix/postfix, enabling derived classes to override this
+*/
+template <typename Range>
+struct dsv_range
+{
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>& os,
+            Range const& range,
+            dsv_settings const& settings)
+    {
+        typedef typename boost::range_const_iterator<Range>::type iterator_type;
+
+        bool first = true;
+
+        os << settings.list_open;
+
+        for (iterator_type it = boost::begin(range);
+            it != boost::end(range);
+            ++it)
+        {
+            os << (first ? "" : settings.point_separator)
+                << settings.point_open;
+
+            stream_coordinate
+                <
+                    point_type, 0, dimension<point_type>::type::value
+                >::apply(os, *it, settings);
+            os << settings.point_close;
+
+            first = false;
+        }
+
+        os << settings.list_close;
+    }
+
+private:
+    typedef typename boost::range_value<Range>::type point_type;
+};
+
+/*!
+\brief Stream sequence of points as DSV-part, e.g. (1 2),(3 4)
+\note Used in polygon, all multi-geometries
+*/
+
+
+
+
+
+template <typename Polygon>
+struct dsv_poly
+{
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>& os,
+                Polygon const& poly,
+                dsv_settings const& settings)
+    {
+        typedef typename ring_type<Polygon>::type ring;
+        typedef typename boost::range_const_iterator
+            <
+                typename interior_type<Polygon>::type
+            >::type iterator_type;
+
+        os << settings.list_open;
+
+        dsv_range<ring>::apply(os, exterior_ring(poly), settings);
+        for (iterator_type it = boost::begin(interior_rings(poly));
+            it != boost::end(interior_rings(poly));
+            ++it)
+        {
+            os << settings.list_separator;
+            dsv_range<ring>::apply(os, *it, settings);
+        }
+        os << settings.list_close;
+    }
+};
+
+template <typename Geometry, std::size_t Index>
+struct dsv_per_index
+{
+    typedef typename point_type<Geometry>::type point_type;
+
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>& os,
+            Geometry const& geometry,
+            dsv_settings const& settings)
+    {
+        os << settings.point_open;
+        stream_indexed
+            <
+                Geometry, Index, 0, dimension<Geometry>::type::value
+            >::apply(os, geometry, settings);
+        os << settings.point_close;
+    }
+};
+
+
+template <typename Geometry>
+struct dsv_indexed
+{
+    typedef typename point_type<Geometry>::type point_type;
+
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>& os,
+            Geometry const& geometry,
+            dsv_settings const& settings)
+    {
+        os << settings.list_open;
+        dsv_per_index<Geometry, 0>::apply(os, geometry, settings);
+        os << settings.point_separator;
+        dsv_per_index<Geometry, 1>::apply(os, geometry, settings);
+        os << settings.list_close;
+    }
+};
+
+}} // namespace detail::dsv
+#endif // DOXYGEN_NO_DETAIL
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch {
+
+template <typename Tag, bool IsMulti, typename Geometry>
+struct dsv {};
+
+
+template <typename Point>
+struct dsv<point_tag, false, Point>
+    : detail::dsv::dsv_point<Point>
+{};
+
+
+template <typename Linestring>
+struct dsv<linestring_tag, false, Linestring>
+    : detail::dsv::dsv_range<Linestring>
+{};
+
+
+template <typename Box>
+struct dsv<box_tag, false, Box>
+    : detail::dsv::dsv_indexed<Box>
+{};
+
+template <typename Segment>
+struct dsv<segment_tag, false, Segment>
+    : detail::dsv::dsv_indexed<Segment>
+{};
+
+
+template <typename Ring>
+struct dsv<ring_tag, false, Ring>
+    : detail::dsv::dsv_range<Ring>
+{};
+
+
+template <typename Polygon>
+struct dsv<polygon_tag, false, Polygon>
+    : detail::dsv::dsv_poly<Polygon>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace dsv {
+
+
+
+template <typename Geometry>
+class dsv_manipulator
+{
+public:
+
+    inline dsv_manipulator(Geometry const& g,
+            dsv_settings const& settings)
+        : m_geometry(g)
+        , m_settings(settings)
+    {}
+
+    template <typename Char, typename Traits>
+    inline friend std::basic_ostream<Char, Traits>& operator<<(
+            std::basic_ostream<Char, Traits>& os,
+            dsv_manipulator const& m)
+    {
+        dispatch::dsv
+            <
+                typename tag<Geometry>::type,
+                is_multi<Geometry>::type::value,
+                Geometry
+            >::apply(os, m.m_geometry, m.m_settings);
+        os.flush();
+        return os;
+    }
+
+private:
+    Geometry const& m_geometry;
+    dsv_settings m_settings;
+};
+
+}} // namespace detail::dsv
+#endif // DOXYGEN_NO_DETAIL
+
+
+/*!
+\brief Main DSV-streaming function
+\details DSV stands for Delimiter Separated Values. Geometries can be streamed
+    as DSV. There are defaults for all separators.
+\note Useful for examples and testing purposes
+\note With this function GeoJSON objects can be created, using the right
+    delimiters
+\ingroup utility
+*/
+template <typename Geometry>
+inline detail::dsv::dsv_manipulator<Geometry> dsv(Geometry const& geometry
+    , std::string const& coordinate_separator = ", "
+    , std::string const& point_open = "("
+    , std::string const& point_close = ")"
+    , std::string const& point_separator = ", "
+    , std::string const& list_open = "("
+    , std::string const& list_close = ")"
+    , std::string const& list_separator = ", "
+    )
+{
+    concept::check<const Geometry>();
+
+    return detail::dsv::dsv_manipulator<Geometry>(geometry,
+        detail::dsv::dsv_settings(coordinate_separator,
+            point_open, point_close, point_separator,
+            list_open, list_close, list_separator));
+}
+
+
+
+} // namespace ggl
+
+#endif // GGL_UTIL_WRITE_DSV_HPP