Last active
December 10, 2015 17:38
-
-
Save bo0ts/4468543 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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