Some bug fixes in CMap and LCC:

* Bugfix in Combinatorial_map::copy and Combinatorial_map::swap
* Bugfix in erase dart if automatic attribute are disabled
* Add missing operator= in Linear_cell_complex
* Remove deprecated code in Linear_cell_complex storage (code which was already removed in Combinatorial_map_storage and not in LCC)
* add const for isomorphic function
This commit is contained in:
Guillaume Damiand 2016-09-28 17:03:38 -04:00
parent e2691e0123
commit 0073b85d7e
6 changed files with 107 additions and 69 deletions

View File

@ -84,6 +84,8 @@ namespace CGAL {
friend struct internal::Reverse_orientation_of_connected_component_functor; friend struct internal::Reverse_orientation_of_connected_component_functor;
template<typename CMap> template<typename CMap>
friend struct internal::Init_attribute_functor; friend struct internal::Init_attribute_functor;
template<typename CMap>
friend struct Swap_attributes_functor;
public: public:
template < unsigned int A, class B, class I, class D, class S > template < unsigned int A, class B, class I, class D, class S >
@ -203,10 +205,13 @@ namespace CGAL {
this->mnb_used_marks = amap.mnb_used_marks; this->mnb_used_marks = amap.mnb_used_marks;
this->mmask_marks = amap.mmask_marks; this->mmask_marks = amap.mmask_marks;
this->automatic_attributes_management =
amap.automatic_attributes_management;
for (size_type i = 0; i < NB_MARKS; ++i) for (size_type i = 0; i < NB_MARKS; ++i)
{ {
this->mfree_marks_stack[i] = amap.mfree_marks_stack[i]; this->mfree_marks_stack[i] = amap.mfree_marks_stack[i];
this->mused_marks_stack[i] = amap.mused_marks_stack[i];
this->mindex_marks[i] = amap.mindex_marks[i]; this->mindex_marks[i] = amap.mindex_marks[i];
this->mnb_marked_darts[i] = amap.mnb_marked_darts[i]; this->mnb_marked_darts[i] = amap.mnb_marked_darts[i];
this->mnb_times_reserved_marks[i] = amap.mnb_times_reserved_marks[i]; this->mnb_times_reserved_marks[i] = amap.mnb_times_reserved_marks[i];
@ -323,7 +328,10 @@ namespace CGAL {
{ {
if (this!=&amap) if (this!=&amap)
{ {
amap.mdarts.swap(mdarts); mdarts.swap(amap.mdarts);
Helper::template Foreach_enabled_attributes
< internal::Swap_attributes_functor <Self> >::run(this, &amap);
std::swap_ranges(mnb_times_reserved_marks, std::swap_ranges(mnb_times_reserved_marks,
mnb_times_reserved_marks+NB_MARKS, mnb_times_reserved_marks+NB_MARKS,
@ -338,9 +346,11 @@ namespace CGAL {
amap.mused_marks_stack); amap.mused_marks_stack);
std::swap_ranges(mnb_marked_darts,mnb_marked_darts+NB_MARKS, std::swap_ranges(mnb_marked_darts,mnb_marked_darts+NB_MARKS,
amap.mnb_marked_darts); amap.mnb_marked_darts);
mattribute_containers.swap(amap.mattribute_containers);
std::swap(null_dart_handle, amap.null_dart_handle); std::swap(null_dart_handle, amap.null_dart_handle);
this->mnull_dart_container.swap(amap.mnull_dart_container); this->mnull_dart_container.swap(amap.mnull_dart_container);
std::swap(automatic_attributes_management,
amap.automatic_attributes_management);
} }
} }
@ -487,8 +497,11 @@ namespace CGAL {
} }
// 2) We update the attribute_ref_counting. // 2) We update the attribute_ref_counting.
Helper::template Foreach_enabled_attributes if ( are_attributes_automatically_managed() )
<internal::Decrease_attribute_functor<Self> >::run(this,adart); {
Helper::template Foreach_enabled_attributes
<internal::Decrease_attribute_functor<Self> >::run(this,adart);
}
// 3) We erase the dart. // 3) We erase the dart.
mdarts.erase(adart); mdarts.erase(adart);
@ -2455,6 +2468,7 @@ namespace CGAL {
if ( marks[acells[i]]==INVALID_MARK ) if ( marks[acells[i]]==INVALID_MARK )
{ {
marks[acells[i]] = get_new_mark(); marks[acells[i]] = get_new_mark();
assert(is_whole_map_unmarked(marks[acells[i]]));
} }
} }
@ -3693,7 +3707,7 @@ namespace CGAL {
class Storage2> class Storage2>
bool is_isomorphic_to(const Combinatorial_map_base bool is_isomorphic_to(const Combinatorial_map_base
<d2,Refs2,Items2,Alloc2, Storage2>& map2, <d2,Refs2,Items2,Alloc2, Storage2>& map2,
bool testAttributes=true) bool testAttributes=true) const
{ {
// if ( dimension!=map2.dimension ) return false; // if ( dimension!=map2.dimension ) return false;

View File

@ -34,6 +34,9 @@
* internal/Combinatorial_map_group_functors.h. Public functions are defined * internal/Combinatorial_map_group_functors.h. Public functions are defined
* in Combinatorial_map_functors.h. * in Combinatorial_map_functors.h.
* *
* internal::Swap_attributes_functor<CMap> to swap the i-attributes between
* two cmaps having same type
*
* internal::Call_split_functor<CMap,i> to call the OnSplit functors on two * internal::Call_split_functor<CMap,i> to call the OnSplit functors on two
* given i-attributes. * given i-attributes.
* *
@ -85,6 +88,20 @@ struct Is_attribute_has_point;
namespace internal namespace internal
{ {
// **************************************************************************** // ****************************************************************************
/// Swap i-attribute between the two maps having same type.
template<typename CMap>
struct Swap_attributes_functor
{
template<unsigned int i>
static void run( CMap* cmap1,
CMap* cmap2)
{ CGAL::cpp11::get<CMap::Helper::template Dimension_index<i>::value>
(cmap1->mattribute_containers).swap(
CGAL::cpp11::get<CMap::Helper::template Dimension_index<i>::value>
(cmap2->mattribute_containers));
}
};
// ****************************************************************************
// Functor which call Functor::operator() on the two given cell_attributes // Functor which call Functor::operator() on the two given cell_attributes
template<typename CMap, typename Cell_attribute, typename Functor> template<typename CMap, typename Cell_attribute, typename Functor>
struct Apply_cell_functor struct Apply_cell_functor

View File

@ -153,6 +153,20 @@ namespace CGAL {
{ Base::template copy<LCC2, Converters, Pointconverter> { Base::template copy<LCC2, Converters, Pointconverter>
(alcc, converters, pointconverter);} (alcc, converters, pointconverter);}
/** Affectation operation. Copies one map to the other.
* @param amap a lcc.
* @return A copy of that lcc.
*/
Self & operator= (const Self & alcc)
{
if (this!=&alcc)
{
Self tmp(alcc);
this->swap(tmp);
}
return *this;
}
/** Create a vertex attribute. /** Create a vertex attribute.
* @return an handle on the new attribute. * @return an handle on the new attribute.
*/ */
@ -478,7 +492,7 @@ namespace CGAL {
are_facets_same_geometry(*it1,beta(*it2, 0)) ) are_facets_same_geometry(*it1,beta(*it2, 0)) )
{ {
++res; ++res;
this->template sew<3>(*it1,beta(*it2, 0)); this->template sew<3>(*it1,this->beta(*it2, 0));
} }
} }
} }

View File

@ -65,7 +65,7 @@ namespace CGAL {
typedef typename Dart_container::size_type size_type; typedef typename Dart_container::size_type size_type;
typedef CGAL::Void* Null_handle_type; typedef CGAL::Void* Null_handle_type;
static Null_handle_type null_handle; static const Null_handle_type null_handle;
typedef Items_ Items; typedef Items_ Items;
typedef Alloc_ Alloc; typedef Alloc_ Alloc;
@ -86,14 +86,14 @@ namespace CGAL {
{}; {};
template<int i> template<int i>
struct Attribute_const_handle: struct Attribute_const_handle:
public Helper::template Attribute_const_handle<i> public Helper::template Attribute_const_handle<i>
{}; {};
template<int i> template<int i>
struct Attribute_range: public Helper::template Attribute_range<i> struct Attribute_range: public Helper::template Attribute_range<i>
{}; {};
template<int i> template<int i>
struct Attribute_const_range: struct Attribute_const_range:
public Helper::template Attribute_const_range<i> public Helper::template Attribute_const_range<i>
{}; {};
typedef typename Attribute_type<0>::type Vertex_attribute; typedef typename Attribute_type<0>::type Vertex_attribute;
@ -116,21 +116,15 @@ namespace CGAL {
// Init // Init
void init_storage() void init_storage()
{ {
#ifdef CGAL_CMAP_DEPRECATED // emplace null_dart; initialized in Combinatorial_map class
// We must do this ony once, but problem because null_dart_handle null_dart_handle = mnull_dart_container.emplace();
// is static !
if ( mnull_dart_container.empty() )
#endif // CGAL_CMAP_DEPRECATED
{ // emplace null_dart; initialized in Combinatorial_map class
null_dart_handle = mnull_dart_container.emplace();
}
} }
/** Return if this dart is free for adimension. /** Return if this dart is free for adimension.
* @param dh a dart handle * @param dh a dart handle
* @param i the dimension. * @param i the dimension.
* @return true iff dh is linked with NULL for \em adimension. * @return true iff dh is linked with NULL for \em adimension.
*/ */
template<unsigned int i> template<unsigned int i>
bool is_free(Dart_const_handle dh) const bool is_free(Dart_const_handle dh) const
{ {
@ -208,24 +202,24 @@ namespace CGAL {
typename Attribute_handle<i>::type attribute(Dart_handle ADart) typename Attribute_handle<i>::type attribute(Dart_handle ADart)
{ {
CGAL_static_assertion_msg(Helper::template Dimension_index<i>::value>=0, CGAL_static_assertion_msg(Helper::template Dimension_index<i>::value>=0,
"attribute<i> called but i-attributes are disabled."); "attribute<i> called but i-attributes are disabled.");
return CGAL::cpp11::get<Helper::template Dimension_index<i>::value> return CGAL::cpp11::get<Helper::template Dimension_index<i>::value>
(ADart->mattribute_handles); (ADart->mattribute_handles);
} }
template<unsigned int i> template<unsigned int i>
typename Attribute_const_handle<i>::type typename Attribute_const_handle<i>::type
attribute(Dart_const_handle ADart) const attribute(Dart_const_handle ADart) const
{ {
CGAL_static_assertion_msg(Helper::template Dimension_index<i>::value>=0, CGAL_static_assertion_msg(Helper::template Dimension_index<i>::value>=0,
"attribute<i> called but i-attributes are disabled."); "attribute<i> called but i-attributes are disabled.");
return CGAL::cpp11::get<Helper::template Dimension_index<i>::value> return CGAL::cpp11::get<Helper::template Dimension_index<i>::value>
(ADart->mattribute_handles); (ADart->mattribute_handles);
} }
// get the attribute given its handle // get the attribute given its handle
template<unsigned int i> template<unsigned int i>
typename Attribute_type<i>::type& get_attribute typename Attribute_type<i>::type&
(typename Attribute_handle<i>::type ah) get_attribute(typename Attribute_handle<i>::type ah)
{ {
CGAL_assertion( ah!=NULL ); CGAL_assertion( ah!=NULL );
return *ah; return *ah;
@ -257,8 +251,8 @@ namespace CGAL {
return ah->dart(); return ah->dart();
} }
template<unsigned int i> template<unsigned int i>
Dart_const_handle dart_of_attribute Dart_const_handle
(typename Attribute_const_handle<i>::type ah) const dart_of_attribute(typename Attribute_const_handle<i>::type ah) const
{ {
CGAL_assertion( ah!=NULL ); CGAL_assertion( ah!=NULL );
return ah->dart(); return ah->dart();
@ -289,7 +283,7 @@ namespace CGAL {
return ah->info(); return ah->info();
} }
// Get the info of the given dart // Get the info of the i-cell attribute associated with the given dart
template<unsigned int i> template<unsigned int i>
typename Attribute_type<i>::type::Info & info(Dart_handle adart) typename Attribute_type<i>::type::Info & info(Dart_handle adart)
{ {
@ -350,14 +344,14 @@ namespace CGAL {
typename Attribute_handle<i>::type ah) typename Attribute_handle<i>::type ah)
{ {
CGAL::cpp11::get<Helper::template Dimension_index<i>::value> CGAL::cpp11::get<Helper::template Dimension_index<i>::value>
(dh->mattribute_handles) = ah; (dh->mattribute_handles) = ah;
} }
/** Link a dart with a given dart for a given dimension. /** Link a dart with a given dart for a given dimension.
* @param adart the dart to link. * @param adart the dart to link.
* @param adart2 the dart to link with. * @param adart2 the dart to link with.
* @param i the dimension. * @param i the dimension.
*/ */
template<unsigned int i> template<unsigned int i>
void dart_link_beta(Dart_handle adart, Dart_handle adart2) void dart_link_beta(Dart_handle adart, Dart_handle adart2)
{ {
@ -375,9 +369,9 @@ namespace CGAL {
} }
/** Unlink a dart for a given dimension. /** Unlink a dart for a given dimension.
* @param adart a dart. * @param adart a dart.
* @param i the dimension. * @param i the dimension.
*/ */
template<unsigned int i> template<unsigned int i>
void dart_unlink_beta(Dart_handle adart) void dart_unlink_beta(Dart_handle adart)
{ {
@ -392,9 +386,6 @@ namespace CGAL {
public: public:
/// Void dart. A dart d is i-free if beta_i(d)=null_dart_handle. /// Void dart. A dart d is i-free if beta_i(d)=null_dart_handle.
#ifdef CGAL_CMAP_DEPRECATED
static
#endif // CGAL_CMAP_DEPRECATED
Dart_handle null_dart_handle; // Todo Dart_const_handle ?? Dart_handle null_dart_handle; // Todo Dart_const_handle ??
protected: protected:
@ -402,9 +393,6 @@ namespace CGAL {
Dart_container mdarts; Dart_container mdarts;
/// Container for the null_dart_handle, static data member. /// Container for the null_dart_handle, static data member.
#ifdef CGAL_CMAP_DEPRECATED
static
#endif // CGAL_CMAP_DEPRECATED
Dart_container mnull_dart_container; Dart_container mnull_dart_container;
/// Tuple of attributes containers /// Tuple of attributes containers
@ -414,33 +402,11 @@ namespace CGAL {
/// null_handle /// null_handle
template <unsigned int d_, unsigned int ambient_dim, template <unsigned int d_, unsigned int ambient_dim,
class Traits_, class Items_, class Alloc_ > class Traits_, class Items_, class Alloc_ >
typename Linear_cell_complex_storage_1<d_, ambient_dim, Traits_, const typename Linear_cell_complex_storage_1<d_, ambient_dim, Traits_,
Items_, Alloc_>::Null_handle_type Items_, Alloc_>::Null_handle_type
Linear_cell_complex_storage_1<d_, ambient_dim, Traits_, Linear_cell_complex_storage_1<d_, ambient_dim, Traits_,
Items_, Alloc_>::null_handle = NULL; Items_, Alloc_>::null_handle = NULL;
#ifdef CGAL_CMAP_DEPRECATED
/// Allocation of static data members
/// mnull_dart_container
template <unsigned int d_, unsigned int ambient_dim,
class Traits_, class Items_, class Alloc_ >
typename Linear_cell_complex_storage_1<d_, ambient_dim, Traits_,
Items_, Alloc_>::Dart_container
Linear_cell_complex_storage_1<d_, ambient_dim, Traits_,
Items_, Alloc_>::mnull_dart_container;
/// null_dart_handle
template <unsigned int d_, unsigned int ambient_dim,
class Traits_, class Items_, class Alloc_ >
typename Linear_cell_complex_storage_1<d_, ambient_dim, Traits_,
Items_, Alloc_>::Dart_handle
Linear_cell_complex_storage_1<d_, ambient_dim, Traits_,
Items_, Alloc_>::null_dart_handle;
// = mnull_dart_container.emplace( std::bitset<NB_MARKS>() );
// Does not work on windows => segfault
// Thus we initialize null_dart_handle in the Combinatorial_map constructor
#endif // CGAL_CMAP_DEPRECATED
} // namespace CGAL } // namespace CGAL
#if (BOOST_GCC >= 40900) #if (BOOST_GCC >= 40900)

View File

@ -104,7 +104,7 @@ void display_lcc(LCC& lcc)
for ( unsigned int i=0; i<=LCC::dimension; ++i) for ( unsigned int i=0; i<=LCC::dimension; ++i)
{ {
std::cout << &(*it->beta(i)) << ",\t"; std::cout << &(*it->beta(i)) << ",\t";
if (it->is_free(i)) std::cout << "\t"; if (lcc.is_free(it, i)) std::cout << "\t";
} }
std::cout<<it->template attribute<0>()->point(); std::cout<<it->template attribute<0>()->point();
std::cout << std::endl; std::cout << std::endl;
@ -130,6 +130,29 @@ bool test_LCC_2()
if ( !check_number_of_cells_2(lcc, 6, 3, 6, 3) ) if ( !check_number_of_cells_2(lcc, 6, 3, 6, 3) )
return false; return false;
{ // Test swap operator
LCC lcc2;
lcc2.swap(lcc);
if ( !check_number_of_cells_2(lcc, 0, 0, 0, 0) )
return false;
if ( !check_number_of_cells_2(lcc2, 6, 3, 6, 3) )
return false;
lcc.swap(lcc2);
if ( !check_number_of_cells_2(lcc2, 0, 0, 0, 0) )
return false;
if ( !check_number_of_cells_2(lcc, 6, 3, 6, 3) )
return false;
// And test operator=
LCC lcc3;
lcc3=lcc;
if ( !check_number_of_cells_2(lcc3, 6, 3, 6, 3) )
return false;
if (!lcc.is_isomorphic_to(lcc3))
return false;
}
typename LCC::Vertex_attribute_handle vh=lcc.template attribute<0>(dh1); typename LCC::Vertex_attribute_handle vh=lcc.template attribute<0>(dh1);
if (!lcc.template is_attribute_used<0>(vh)) return false; if (!lcc.template is_attribute_used<0>(vh)) return false;

View File

@ -664,6 +664,10 @@ bool testCopy()
map5b.number_of_attributes<2>()==map5.number_of_attributes<2>() && map5b.number_of_attributes<2>()==map5.number_of_attributes<2>() &&
map5b.number_of_attributes<3>()==map5.number_of_attributes<3>() ); map5b.number_of_attributes<3>()==map5.number_of_attributes<3>() );
assert( map5b.is_isomorphic_to(map5)==map5.is_isomorphic_to(map5b) ); assert( map5b.is_isomorphic_to(map5)==map5.is_isomorphic_to(map5b) );
Map9 map5c;
map5c=map5b; // To test operator=
if ( !map5c.is_isomorphic_to(map5b) ) { assert(false); return false; }
} }
/*map2.display_characteristics(std::cout)<<std::endl; /*map2.display_characteristics(std::cout)<<std::endl;