1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
//! The [`Geometry`] super-trait: every concept refines it.
//!
//! Mirrors the role of the two C++ trait metafunctions
//! `boost::geometry::traits::tag<G>::type`
//! (`boost/geometry/core/tag.hpp`) and
//! `boost::geometry::traits::point_type<G>::type`
//! (`boost/geometry/core/point_type.hpp`): every modelled geometry
//! exposes (a) its kind, as one of the `*Tag` types from
//! [`geometry_tag`], and (b) the point type its coordinates live in.
//!
//! Splitting these two pieces out into a single Rust super-trait
//! lets every other concept (Point, Segment, Box, Linestring, Ring,
//! Polygon, …) refine `Geometry<Kind = …>` and inherit the
//! `type Point` projection without re-stating it.
use cratePoint;
/// Every modelled geometry has a *kind* (its tag) and a *point type*
/// it is built from.
///
/// `Kind` matches `boost::geometry::traits::tag<G>::type`
/// (`boost/geometry/core/tag.hpp`); `Point` matches
/// `boost::geometry::traits::point_type<G>::type`
/// (`boost/geometry/core/point_type.hpp`). For a value whose own
/// kind is [`geometry_tag::PointTag`], the `Point` projection is
/// `Self`.
///
/// # Examples
///
/// Dispatch on the geometry kind via the `Kind` associated type:
///
/// ```
/// use geometry_tag::PointTag;
/// use geometry_trait::Geometry;
///
/// fn is_point<G: Geometry<Kind = PointTag>>(_g: &G) {}
/// ```