AABB-tree bugfix: perfect forward of arguments in C++11 and by ref otherwise

this was a bug because the shared data were copied
This commit is contained in:
Sébastien Loriot 2014-07-02 12:23:52 +02:00
parent 326b604e58
commit 5d9219c96d
2 changed files with 72 additions and 67 deletions

View File

@ -53,10 +53,10 @@ template <class Primitive>
struct AABB_traits_base<Primitive,true>{
typename Primitive::Shared_data m_primitive_data;
#ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES
#if !defined(CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES) && !defined(CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE)
template <typename ... T>
void set_shared_data(T ... t){
m_primitive_data=Primitive::construct_shared_data(t...);
void set_shared_data(T&& ... t){
m_primitive_data=Primitive::construct_shared_data(std::forward<T>(t)...);
}
#else
void set_shared_data(){
@ -64,22 +64,27 @@ struct AABB_traits_base<Primitive,true>{
}
template <class T1>
void set_shared_data(T1 t1){
void set_shared_data(T1& t1){
m_primitive_data=Primitive::construct_shared_data(t1);
}
template <class T1,class T2>
void set_shared_data(T1& t1, T2& t2){
m_primitive_data=Primitive::construct_shared_data(t1,t2);
}
template <class T1,class T2,class T3>
void set_shared_data(T1 t1,T2 t2,T3 t3){
void set_shared_data(T1& t1,T2& t2,T3& t3){
m_primitive_data=Primitive::construct_shared_data(t1,t2,t3);
}
template <class T1,class T2,class T3,class T4>
void set_shared_data(T1 t1,T2 t2,T3 t3,T4 t4){
void set_shared_data(T1& t1,T2& t2,T3& t3,T4& t4){
m_primitive_data=Primitive::construct_shared_data(t1,t2,t3,t4);
}
template <class T1,class T2,class T3,class T4,class T5>
void set_shared_data(T1 t1,T2 t2,T3 t3,T4 t4,T5 t5){
void set_shared_data(T1& t1,T2& t2,T3& t3,T4& t4,T5& t5){
m_primitive_data=Primitive::construct_shared_data(t1,t2,t3,t4,t5);
}
#endif

View File

@ -124,22 +124,22 @@ namespace CGAL {
* 5 template arguments are provided.
* The tree stays empty if the memory allocation is not successful.
*/
#ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES
#if !defined(CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES) && !defined(CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE)
template<typename InputIterator,typename ... T>
AABB_tree(InputIterator first, InputIterator beyond,T...);
AABB_tree(InputIterator first, InputIterator beyond,T&& ...);
#else
template<typename InputIterator>
AABB_tree(InputIterator first, InputIterator beyond);
template<typename InputIterator, typename T1>
AABB_tree(InputIterator first, InputIterator beyond,T1);
AABB_tree(InputIterator first, InputIterator beyond, T1&);
template<typename InputIterator, typename T1, typename T2>
AABB_tree(InputIterator first, InputIterator beyond,T1,T2);
AABB_tree(InputIterator first, InputIterator beyond,T1&,T2&);
template<typename InputIterator, typename T1, typename T2, typename T3>
AABB_tree(InputIterator first, InputIterator beyond,T1,T2,T3);
AABB_tree(InputIterator first, InputIterator beyond,T1&,T2&,T3&);
template<typename InputIterator, typename T1, typename T2, typename T3, typename T4>
AABB_tree(InputIterator first, InputIterator beyond,T1,T2,T3,T4);
AABB_tree(InputIterator first, InputIterator beyond,T1&,T2&,T3&,T4&);
template<typename InputIterator, typename T1, typename T2, typename T3, typename T4, typename T5>
AABB_tree(InputIterator first, InputIterator beyond,T1,T2,T3,T4,T5);
AABB_tree(InputIterator first, InputIterator beyond,T1&,T2&,T3&,T4&,T5&);
#endif
///@}
@ -150,22 +150,22 @@ namespace CGAL {
/// Equivalent to calling `clear()` and then `insert(first,last,t...)`.
/// For compilers that do not support variadic templates, overloads up
/// to 5 template arguments are provided.
#ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES
#if !defined(CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES) && !defined(CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE)
template<typename ConstPrimitiveIterator,typename ... T>
void rebuild(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond,T...);
void rebuild(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond,T&& ...);
#else
template<typename ConstPrimitiveIterator>
void rebuild(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond);
template<typename ConstPrimitiveIterator, typename T1>
void rebuild(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond,T1);
void rebuild(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond, T1&);
template<typename ConstPrimitiveIterator, typename T1, typename T2>
void rebuild(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond,T1,T2);
void rebuild(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond,T1&,T2&);
template<typename ConstPrimitiveIterator, typename T1, typename T2, typename T3>
void rebuild(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond,T1,T2,T3);
void rebuild(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond,T1&,T2&,T3&);
template<typename ConstPrimitiveIterator, typename T1, typename T2, typename T3, typename T4>
void rebuild(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond,T1,T2,T3,T4);
void rebuild(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond,T1&,T2&,T3&,T4&);
template<typename ConstPrimitiveIterator, typename T1, typename T2, typename T3, typename T4, typename T5>
void rebuild(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond,T1,T2,T3,T4,T5);
void rebuild(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond,T1&,T2&,T3&,T4&,T5&);
#endif
@ -177,22 +177,22 @@ namespace CGAL {
/// is made using the internally stored traits.
/// For compilers that do not support variadic templates,
/// overloads up to 5 template arguments are provided.
#ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES
#if !defined(CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES) && !defined(CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE)
template<typename InputIterator,typename ... T>
void insert(InputIterator first, InputIterator beyond,T...);
void insert(InputIterator first, InputIterator beyond,T&& ...);
#else
template<typename InputIterator>
void insert(InputIterator first, InputIterator beyond);
template<typename InputIterator, typename T1>
void insert(InputIterator first, InputIterator beyond,T1);
void insert(InputIterator first, InputIterator beyond,T1&);
template<typename InputIterator, typename T1, typename T2>
void insert(InputIterator first, InputIterator beyond,T1,T2);
void insert(InputIterator first, InputIterator beyond,T1&, T2&);
template<typename InputIterator, typename T1, typename T2, typename T3>
void insert(InputIterator first, InputIterator beyond,T1,T2,T3);
void insert(InputIterator first, InputIterator beyond,T1&,T2&,T3&);
template<typename InputIterator, typename T1, typename T2, typename T3, typename T4>
void insert(InputIterator first, InputIterator beyond,T1,T2,T3,T4);
void insert(InputIterator first, InputIterator beyond,T1&,T2&,T3&,T4&);
template<typename InputIterator, typename T1, typename T2, typename T3, typename T4, typename T5>
void insert(InputIterator first, InputIterator beyond,T1,T2,T3,T4,T5);
void insert(InputIterator first, InputIterator beyond,T1&,T2&,T3&,T4&,T5&);
#endif
/// Adds a primitive to the set of primitives of the tree.
@ -251,16 +251,16 @@ namespace CGAL {
///@}
private:
#ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES
#if !defined(CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES) && !defined(CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE)
template <typename ... T>
void set_primitive_data_impl(CGAL::Boolean_tag<false>,T ... ){}
template <typename ... T>
void set_primitive_data_impl(CGAL::Boolean_tag<true>,T ... t)
{m_traits.set_shared_data(t...);}
void set_primitive_data_impl(CGAL::Boolean_tag<true>,T&& ... t)
{m_traits.set_shared_data(std::forward<T>(t)...);}
template <typename ... T>
void set_shared_data(T...t){
set_primitive_data_impl(CGAL::Boolean_tag<internal::Has_nested_type_Shared_data<Primitive>::value>(),t...);
void set_shared_data(T&& ...t){
set_primitive_data_impl(CGAL::Boolean_tag<internal::Has_nested_type_Shared_data<Primitive>::value>(),std::forward<T>(t)...);
}
#else
void set_primitive_data_impl(CGAL::Boolean_tag<false>){}
@ -273,50 +273,50 @@ private:
template <typename T1>
void set_primitive_data_impl(CGAL::Boolean_tag<false>,T1){}
template <typename T1>
void set_primitive_data_impl(CGAL::Boolean_tag<true>,T1 t1)
void set_primitive_data_impl(CGAL::Boolean_tag<true>,T1& t1)
{m_traits.set_shared_data(t1);}
template <typename T1>
void set_shared_data(T1 t1){
void set_shared_data(T1& t1){
set_primitive_data_impl(Boolean_tag<internal::Has_nested_type_Shared_data<Primitive>::value>(),t1);
}
template <typename T1, typename T2>
void set_primitive_data_impl(CGAL::Boolean_tag<false>,T1,T2){}
template <typename T1, typename T2>
void set_primitive_data_impl(CGAL::Boolean_tag<true>,T1 t1,T2 t2)
void set_primitive_data_impl(CGAL::Boolean_tag<true>,T1& t1,T2& t2)
{m_traits.set_shared_data(t1,t2);}
template <typename T1, typename T2>
void set_shared_data(T1 t1,T2 t2){
void set_shared_data(const T1& t1,const T2& t2){
set_primitive_data_impl(Boolean_tag<internal::Has_nested_type_Shared_data<Primitive>::value>(),t1,t2);
}
template <typename T1, typename T2, typename T3>
void set_primitive_data_impl(CGAL::Boolean_tag<false>,T1,T2,T3){}
template <typename T1, typename T2, typename T3>
void set_primitive_data_impl(CGAL::Boolean_tag<true>,T1 t1,T2 t2,T3 t3)
void set_primitive_data_impl(CGAL::Boolean_tag<true>,T1& t1,T2& t2,T3& t3)
{m_traits.set_shared_data(t1,t2,t3);}
template <typename T1, typename T2, typename T3>
void set_shared_data(T1 t1,T2 t2,T3 t3){
void set_shared_data(T1& t1,T2& t2,T3& t3){
set_primitive_data_impl(Boolean_tag<internal::Has_nested_type_Shared_data<Primitive>::value>(),t1,t2,t3);
}
template <typename T1, typename T2, typename T3, typename T4>
void set_primitive_data_impl(CGAL::Boolean_tag<false>,T1,T2,T3,T4){}
template <typename T1, typename T2, typename T3, typename T4>
void set_primitive_data_impl(CGAL::Boolean_tag<true>,T1 t1,T2 t2,T3 t3,T4 t4)
void set_primitive_data_impl(CGAL::Boolean_tag<true>,T1& t1,T2& t2,T3& t3,T4& t4)
{m_traits.set_shared_data(t1,t2,t3,t4);}
template <typename T1, typename T2, typename T3, typename T4>
void set_shared_data(T1 t1,T2 t2,T3 t3,T4 t4){
void set_shared_data(T1& t1,T2& t2,T3& t3,T4& t4){
set_primitive_data_impl(Boolean_tag<internal::Has_nested_type_Shared_data<Primitive>::value>(),t1,t2,t3,t4);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5>
void set_primitive_data_impl(CGAL::Boolean_tag<false>,T1,T2,T3,T4,T5){}
template <typename T1, typename T2, typename T3, typename T4, typename T5>
void set_primitive_data_impl(CGAL::Boolean_tag<true>,T1 t1,T2 t2,T3 t3,T4 t4,T5 t5)
void set_primitive_data_impl(CGAL::Boolean_tag<true>,T1& t1,T2& t2,T3& t3,T4& t4,T5& t5)
{m_traits.set_shared_data(t1,t2,t3,t4,t5);}
template <typename T1, typename T2, typename T3, typename T4, typename T5>
void set_shared_data(T1 t1,T2 t2,T3 t3,T4 t4,T5 t5){
void set_shared_data(T1& t1,T2& t2,T3& t3,T4& t4,T5& t5){
set_primitive_data_impl(Boolean_tag<internal::Has_nested_type_Shared_data<Primitive>::value>(),t1,t2,t3,t4,t5);
}
#endif
@ -648,12 +648,12 @@ public:
, m_need_build(false)
{}
#ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES
#if !defined(CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES) && !defined(CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE)
template<typename Tr>
template<typename ConstPrimitiveIterator, typename ... T>
AABB_tree<Tr>::AABB_tree(ConstPrimitiveIterator first,
ConstPrimitiveIterator beyond,
T ... t)
T&& ... t)
: m_traits()
, m_primitives()
, m_p_root_node(NULL)
@ -663,19 +663,19 @@ public:
, m_need_build(false)
{
// Insert each primitive into tree
insert(first, beyond,t...);
insert(first, beyond,std::forward<T>(t)...);
}
template<typename Tr>
template<typename ConstPrimitiveIterator, typename ... T>
void AABB_tree<Tr>::insert(ConstPrimitiveIterator first,
ConstPrimitiveIterator beyond,
T ... t)
T&& ... t)
{
set_shared_data(t...);
set_shared_data(std::forward<T>(t)...);
while(first != beyond)
{
m_primitives.push_back(Primitive(first,t...));
m_primitives.push_back(Primitive(first,std::forward<T>(t)...));
++first;
}
m_need_build = true;
@ -686,13 +686,13 @@ public:
template<typename ConstPrimitiveIterator, typename ... T>
void AABB_tree<Tr>::rebuild(ConstPrimitiveIterator first,
ConstPrimitiveIterator beyond,
T ... t)
T&& ... t)
{
// cleanup current tree and internal KD tree
clear();
// inserts primitives
insert(first, beyond,t...);
insert(first, beyond,std::forward<T>(t)...);
build();
}
@ -718,7 +718,7 @@ public:
template<typename ConstPrimitiveIterator, typename T1>
AABB_tree<Tr>::AABB_tree(ConstPrimitiveIterator first,
ConstPrimitiveIterator beyond,
T1 t1)
T1& t1)
: m_traits()
, m_primitives()
, m_p_root_node(NULL)
@ -735,7 +735,7 @@ public:
template<typename ConstPrimitiveIterator, typename T1, typename T2>
AABB_tree<Tr>::AABB_tree(ConstPrimitiveIterator first,
ConstPrimitiveIterator beyond,
T1 t1,T2 t2)
T1& t1,T2& t2)
: m_traits()
, m_primitives()
, m_p_root_node(NULL)
@ -752,7 +752,7 @@ public:
template<typename ConstPrimitiveIterator, typename T1, typename T2, typename T3>
AABB_tree<Tr>::AABB_tree(ConstPrimitiveIterator first,
ConstPrimitiveIterator beyond,
T1 t1,T2 t2,T3 t3)
T1& t1,T2& t2,T3& t3)
: m_traits()
, m_primitives()
, m_p_root_node(NULL)
@ -769,7 +769,7 @@ public:
template<typename ConstPrimitiveIterator, typename T1, typename T2, typename T3, typename T4>
AABB_tree<Tr>::AABB_tree(ConstPrimitiveIterator first,
ConstPrimitiveIterator beyond,
T1 t1,T2 t2,T3 t3,T4 t4)
T1& t1,T2& t2,T3& t3,T4& t4)
: m_traits()
, m_primitives()
, m_p_root_node(NULL)
@ -786,7 +786,7 @@ public:
template<typename ConstPrimitiveIterator, typename T1, typename T2, typename T3, typename T4, typename T5>
AABB_tree<Tr>::AABB_tree(ConstPrimitiveIterator first,
ConstPrimitiveIterator beyond,
T1 t1,T2 t2,T3 t3,T4 t4,T5 t5)
T1& t1,T2& t2,T3& t3,T4& t4,T5& t5)
: m_traits()
, m_primitives()
, m_p_root_node(NULL)
@ -817,7 +817,7 @@ public:
template<typename ConstPrimitiveIterator, typename T1>
void AABB_tree<Tr>::insert(ConstPrimitiveIterator first,
ConstPrimitiveIterator beyond,
T1 t1)
T1& t1)
{
set_shared_data(t1);
while(first != beyond)
@ -832,7 +832,7 @@ public:
template<typename ConstPrimitiveIterator, typename T1, typename T2>
void AABB_tree<Tr>::insert(ConstPrimitiveIterator first,
ConstPrimitiveIterator beyond,
T1 t1,T2 t2)
T1& t1, T2& t2)
{
set_shared_data(t1,t2);
while(first != beyond)
@ -847,7 +847,7 @@ public:
template<typename ConstPrimitiveIterator, typename T1, typename T2, typename T3>
void AABB_tree<Tr>::insert(ConstPrimitiveIterator first,
ConstPrimitiveIterator beyond,
T1 t1,T2 t2,T3 t3)
T1& t1,T2& t2,T3& t3)
{
set_shared_data(t1,t2,t3);
while(first != beyond)
@ -862,7 +862,7 @@ public:
template<typename ConstPrimitiveIterator, typename T1, typename T2, typename T3, typename T4>
void AABB_tree<Tr>::insert(ConstPrimitiveIterator first,
ConstPrimitiveIterator beyond,
T1 t1,T2 t2,T3 t3,T4 t4)
T1& t1,T2& t2,T3& t3,T4& t4)
{
set_shared_data(t1,t2,t3,t4);
while(first != beyond)
@ -877,7 +877,7 @@ public:
template<typename ConstPrimitiveIterator, typename T1, typename T2, typename T3, typename T4, typename T5>
void AABB_tree<Tr>::insert(ConstPrimitiveIterator first,
ConstPrimitiveIterator beyond,
T1 t1,T2 t2,T3 t3,T4 t4,T5 t5)
T1& t1,T2& t2,T3& t3,T4& t4,T5& t5)
{
set_shared_data(t1,t2,t3,t4,t5);
while(first != beyond)
@ -888,7 +888,7 @@ public:
m_need_build = true;
}
//=============insert======================
//=============rebuild======================
template<typename Tr>
template<typename ConstPrimitiveIterator>
void AABB_tree<Tr>::rebuild(ConstPrimitiveIterator first,
@ -907,7 +907,7 @@ public:
template<typename ConstPrimitiveIterator, typename T1>
void AABB_tree<Tr>::rebuild(ConstPrimitiveIterator first,
ConstPrimitiveIterator beyond,
T1 t1)
T1& t1)
{
// cleanup current tree and internal KD tree
clear();
@ -922,7 +922,7 @@ public:
template<typename ConstPrimitiveIterator, typename T1, typename T2>
void AABB_tree<Tr>::rebuild(ConstPrimitiveIterator first,
ConstPrimitiveIterator beyond,
T1 t1,T2 t2)
T1& t1, T2& t2)
{
// cleanup current tree and internal KD tree
clear();
@ -937,7 +937,7 @@ public:
template<typename ConstPrimitiveIterator, typename T1, typename T2, typename T3>
void AABB_tree<Tr>::rebuild(ConstPrimitiveIterator first,
ConstPrimitiveIterator beyond,
T1 t1,T2 t2,T3 t3)
T1& t1,T2& t2,T3& t3)
{
// cleanup current tree and internal KD tree
clear();
@ -952,7 +952,7 @@ public:
template<typename ConstPrimitiveIterator, typename T1, typename T2, typename T3, typename T4>
void AABB_tree<Tr>::rebuild(ConstPrimitiveIterator first,
ConstPrimitiveIterator beyond,
T1 t1,T2 t2,T3 t3,T4 t4)
T1& t1,T2& t2,T3& t3,T4& t4)
{
// cleanup current tree and internal KD tree
clear();
@ -967,7 +967,7 @@ public:
template<typename ConstPrimitiveIterator, typename T1, typename T2, typename T3, typename T4, typename T5>
void AABB_tree<Tr>::rebuild(ConstPrimitiveIterator first,
ConstPrimitiveIterator beyond,
T1 t1,T2 t2,T3 t3,T4 t4,T5 t5)
T1& t1,T2& t2,T3& t3,T4& t4,T5& t5)
{
// cleanup current tree and internal KD tree
clear();