Skip to content

Instantly share code, notes, and snippets.

@bo0ts
Last active December 10, 2015 17:38
Show Gist options
  • Save bo0ts/4468543 to your computer and use it in GitHub Desktop.
Save bo0ts/4468543 to your computer and use it in GitHub Desktop.
#ifndef _TDS_H_
#define _TDS_H_
#include <CGAL/config.h>
#include <CGAL/Compact_container.h>
// dimension
#include <boost/mpl/int.hpp>
// for property bundle implementation
#include <boost/static_assert.hpp>
#include <boost/property_map/property_map.hpp>
#include <boost/function_types/is_member_object_pointer.hpp>
#include <boost/function_types/result_type.hpp>
namespace CGAL {
template < typename Dim, typename V, typename F,
typename VertexAllocator = std::allocator<V>,
typename FullCellAllocator = std::allocator<V>
>
class tds {
// declarations
struct full_cell_node;
struct vertex_node;
public:
typedef V vertex_bundle;
typedef F full_cell_bundle;
typedef CGAL::Compact_container<
vertex_node,
typename VertexAllocator::template rebind<vertex_node>::other
> vertex_container;
typedef CGAL::Compact_container<
full_cell_node,
typename FullCellAllocator::template rebind<full_cell_node>::other
> full_cell_container;
// they are also ranges
// iterators
typedef typename vertex_container::iterator vertex_iterator;
typedef typename vertex_container::const_iterator vertex_const_iterator;
typedef vertex_iterator vertex_handle;
typedef vertex_const_iterator vertex_const_handle;
typedef typename full_cell_container::iterator full_cell_iterator;
typedef typename full_cell_container::const_iterator full_cell_const_iterator;
typedef full_cell_iterator full_cell_handle;
typedef full_cell_const_iterator full_cell_const_handle;
// ranges
typedef vertex_container vertex_range;
typedef full_cell_container full_cell_range;
private:
// data
vertex_container vc;
full_cell_container fcc;
public:
// range access
vertex_range& vertices()
{ return vc; }
const vertex_range& vertices() const
{ return vc; }
full_cell_range& full_cells()
{ return fcc; }
const full_cell_range& full_cells() const
{ return fcc; }
private:
// exposition purposes
struct combinatorics {
void* for_compact_container() const
{ return NULL; }
void*& for_compact_container()
{ return NULL; }
};
struct full_cell_data {};
struct full_cell_node {
full_cell_bundle f; // user data
combinatorics combinatorics_;
mutable full_cell_data tds_data_;
// stuff for compact container
void* for_compact_container() const
{ return combinatorics_.for_compact_container(); }
void*& for_compact_container()
{ return combinatorics_.for_compact_container(); }
};
// definitions
struct vertex_node {
// user data
vertex_bundle v;
// aux data
full_cell_handle full_cell_;
// stuff for compact container
void* for_compact_container() const
{ return full_cell_.for_compact_container(); }
void*& for_compact_container()
{ return full_cell_.for_compact_container(); }
};
public:
// property access
vertex_bundle& operator[](vertex_handle h)
{ return h->v; }
const vertex_bundle& operator[](vertex_const_handle h) const
{ return h->v; }
public:
// vertex functionality
void set_full_cell(vertex_handle v, full_cell_handle h) const
{ v->full_cell_ = h; }
full_cell_handle full_cell(vertex_handle v) const
{ return v->full_cell_; }
// full_cell functionality
std::pair<bool, int>
has_neighbor(full_cell_const_handle h, full_cell_const_handle g);
// etc.
};
// vertex properties, this can be unified for full_cell and vertex
// properties. we can also go further and allow member function
// pointers.
template <typename TDS, typename MemberPtrType>
struct vertex_property_map {
BOOST_STATIC_ASSERT((boost::function_types::is_member_object_pointer<MemberPtrType>::value));
vertex_property_map(MemberPtrType mptr) : mptr_(mptr) {}
MemberPtrType mptr_;
// result of ptr-to-member access is always a reference
typedef typename boost::function_types::result_type<MemberPtrType>::type reference;
typedef typename boost::remove_reference<reference> value_type;
typedef typename TDS::vertex_handle key_type;
typedef boost::lvalue_property_map_tag category;
};
template <typename TDS, typename MemberPtrType, typename VertexHandle>
typename vertex_property_map<TDS, MemberPtrType>::reference
get(vertex_property_map<TDS, MemberPtrType>& pmap, typename vertex_property_map<TDS, MemberPtrType>::key_type k)
{ return (k->v).*(pmap.mptr_); }
// incomplete, needs a mechanism to decide between
template <typename MemberPtrType, typename TDS>
vertex_property_map<TDS, MemberPtrType>
get(MemberPtrType mptr, TDS&)
{ return vertex_property_map<TDS, MemberPtrType>(mptr); }
} // CGAL
#endif /* _TDS_H_ */
#include "tds.hpp"
#include <boost/array.hpp>
struct my_vertex { boost::array<double, 20> point; int foo; int bar; };
struct my_face {};
int main()
{
typedef CGAL::tds<boost::mpl::int_<20>, my_vertex, my_face> TDS;
TDS tds;
tds.full_cells();
tds.vertices();
// property access
TDS::vertex_handle h = tds.vertices().begin();
tds[h].point = boost::array<double, 20>();
tds[h].foo = 23;
tds[h].bar = 42;
// property maps from bundles
get(&my_vertex::point, tds);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment