On Github bo0ts / generics-geometry
Philipp Möller
using std::disclaimer;
Continuously raise the level of abstraction over input parameters.
Group those abstractions into Concepts.
Use concept refinement and hierarchies of concepts to expose implementation differences.
David Abrahams, Jeremy Siek
concept Stack<typename X> { typename value_type; void Stack::push(value_type); void Stack::pop(); value_type Stack::top(); bool Stack::empty(); };
concept SinglePassRange<typename X> { typedef iterator_type::type iterator; where SinglePassIterator<iterator>; iterator begin(X&); // notice free functions iterator end(X&); };
namespace mine { struct my_vector { int x[20]; }; int* begin(my_vector& x) { return x; } int* begin(my_vector& x) { return x + 20; } template<> struct iterator_type { typedef int* type; }; }
Not all algorithms require full Halfedge Data Structures. Provide views on types:
Abstract optional features of Halfedge Data Structures into properties.
Algorithms require properties. Mutable algorithms can introspect for available properties and handle them.
template<typename... Options> class Surface_mesh; struct Vertex_properties { Simple_cartesian<double>::Point_3 point; }; Surface_mesh< Vertex_properties<Vertex_properties> , Dynamic_properties<std::true_type>> polyhedron; for(auto& v : vertices(polyhedron)) { // ... }
BOOST_PARAMETER_FUNCTION( (void), join_vertex, tag, (required (graph, *) ) (required (edge, *) ) (optional (next_map, *, boost::get(boost::edge_next, graph)) (prev_map, *, boost::get(boost::edge_prev, graph)) ) ) { my_join_vertex_impl(graph, edge, next_map, prev_map); } join_vertex(my_graph);