mirror of https://github.com/CGAL/cgal
Separate the containers
This commit is contained in:
parent
c7a8299712
commit
7ac6780bb4
|
|
@ -94,9 +94,6 @@ struct Compact_container_with_index_traits {
|
|||
{ t.for_compact_container(v); }
|
||||
};
|
||||
|
||||
template <class, class, class, class>
|
||||
class Compact_container_with_index_2;
|
||||
|
||||
namespace internal {
|
||||
template < class DSC, bool Const>
|
||||
class CC_iterator_with_index;
|
||||
|
|
@ -937,7 +934,7 @@ namespace internal {
|
|||
|
||||
/// Constructor. Default construction creates a kind of "NULL" index.
|
||||
/// max/2 because the most significant bit must be equal to 0 (used).
|
||||
MyIndex(size_type idx=(std::numeric_limits<size_type>::max)()/2)
|
||||
MyIndex(size_type idx=(std::numeric_limits<size_type>::max)()) // TODO /2)
|
||||
: m_idx(idx)
|
||||
{}
|
||||
|
||||
|
|
@ -947,11 +944,11 @@ namespace internal {
|
|||
|
||||
/// reset index to be NULL
|
||||
void reset()
|
||||
{ m_idx = (std::numeric_limits<size_type>::max)()/2; }
|
||||
{ m_idx = (std::numeric_limits<size_type>::max)(); } // TODO /2; }
|
||||
|
||||
/// return whether the handle is valid
|
||||
bool is_valid() const
|
||||
{ return m_idx != (std::numeric_limits<size_type>::max)()/2; }
|
||||
{ return m_idx != (std::numeric_limits<size_type>::max)(); } // TODO /2; }
|
||||
|
||||
// /// are two indices equal?
|
||||
// bool operator==(const Self& rhs) const
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
#ifndef CGAL_COMPACT_CONTAINER_WITH_INDEX_2_H
|
||||
#define CGAL_COMPACT_CONTAINER_WITH_INDEX_2_H
|
||||
|
||||
#include <CGAL/Compact_container_with_index.h>
|
||||
#include <CGAL/Compact_container.h>
|
||||
|
||||
// An STL like container with the following properties :
|
||||
// - to achieve compactness, it requires access to a pointer stored in T,
|
||||
|
|
@ -63,6 +63,45 @@
|
|||
|
||||
namespace CGAL {
|
||||
|
||||
template<unsigned int k>
|
||||
struct Multiply_by_two_policy_for_cc_with_size
|
||||
{
|
||||
static const unsigned int first_block_size = k;
|
||||
|
||||
template<typename Compact_container>
|
||||
static void increase_size(Compact_container& cc)
|
||||
{ cc.block_size=cc.capacity_; }
|
||||
};
|
||||
|
||||
template<unsigned int k>
|
||||
struct Constant_size_policy_for_cc_with_size
|
||||
{
|
||||
static const unsigned int first_block_size = k;
|
||||
|
||||
template<typename Compact_container>
|
||||
static void increase_size(Compact_container& /*cc*/)
|
||||
{}
|
||||
};
|
||||
|
||||
// The traits class describes the way to access the size_type.
|
||||
// It can be specialized.
|
||||
template < class T, class size_type >
|
||||
struct Compact_container_with_index_traits {
|
||||
static size_type size_t(const T &t)
|
||||
{ return t.for_compact_container(); }
|
||||
static void set_size_t(T &t, size_type v)
|
||||
{ t.for_compact_container(v); }
|
||||
};
|
||||
|
||||
namespace internal {
|
||||
template < class DSC, bool Const>
|
||||
class CC_iterator_with_index;
|
||||
|
||||
template < class T, class ST >
|
||||
class MyIndex;
|
||||
}
|
||||
|
||||
|
||||
template<class Index_type>
|
||||
class Index_for_cc_with_index
|
||||
{
|
||||
|
|
@ -594,6 +633,195 @@ void Compact_container_with_index_2<T, Allocator, Increment_policy, IndexType>::
|
|||
Increment_policy::increase_size(*this);
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
|
||||
// **********************************************************************
|
||||
// specialization if we use index: in this case, an iterator use one more
|
||||
// data member of type size_type: memory footprint is more important than
|
||||
// iterator without index. However such iterator is not supposed to be used
|
||||
// in function parameters, to store handles through elements...
|
||||
// We must use indices for that.
|
||||
template < class DSC, bool Const >
|
||||
class CC_iterator_with_index
|
||||
{
|
||||
typedef typename DSC::iterator iterator;
|
||||
typedef CC_iterator_with_index<DSC, Const> Self;
|
||||
|
||||
friend class CC_iterator_with_index<DSC, true>;
|
||||
friend class CC_iterator_with_index<DSC, false>;
|
||||
|
||||
public:
|
||||
typedef typename DSC::value_type value_type;
|
||||
typedef typename DSC::size_type size_type;
|
||||
typedef typename DSC::difference_type difference_type;
|
||||
typedef typename boost::mpl::if_c< Const, const value_type*,
|
||||
value_type*>::type pointer;
|
||||
typedef typename boost::mpl::if_c< Const, const value_type&,
|
||||
value_type&>::type reference;
|
||||
typedef std::bidirectional_iterator_tag iterator_category;
|
||||
|
||||
typedef typename boost::mpl::if_c< Const, const DSC*, DSC*>::type
|
||||
cc_pointer;
|
||||
|
||||
// the initialization with NULL is required by our Handle concept.
|
||||
CC_iterator_with_index() : m_ptr_to_cc(NULL),
|
||||
m_index(0)
|
||||
{}
|
||||
|
||||
// Either a harmless copy-ctor,
|
||||
// or a conversion from iterator to const_iterator.
|
||||
CC_iterator_with_index (const iterator &it) : m_ptr_to_cc(it.m_ptr_to_cc),
|
||||
m_index(it.m_index)
|
||||
{}
|
||||
|
||||
// Same for assignment operator (otherwise MipsPro warns)
|
||||
CC_iterator_with_index & operator= (const iterator &it)
|
||||
{
|
||||
m_ptr_to_cc = it.m_ptr_to_cc;
|
||||
m_index = it.m_index;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Construction from NULL
|
||||
CC_iterator_with_index (Nullptr_t CGAL_assertion_code(n)) :
|
||||
m_ptr_to_cc(NULL),
|
||||
m_index(0)
|
||||
{ CGAL_assertion (n == NULL); }
|
||||
|
||||
operator size_type() const
|
||||
{ return m_index; }
|
||||
|
||||
size_type get_current() const
|
||||
{ return m_index; }
|
||||
|
||||
protected:
|
||||
void set_current(size_type dh)
|
||||
{ m_index = dh; }
|
||||
|
||||
protected:
|
||||
|
||||
// Only Compact_container should access these constructors.
|
||||
//template<class,class,class>
|
||||
friend class Compact_container_with_index_2<value_type, typename DSC::Al,
|
||||
typename DSC::Incr_policy, typename DSC::size_type>;
|
||||
cc_pointer m_ptr_to_cc;
|
||||
size_type m_index;
|
||||
|
||||
// For begin()
|
||||
CC_iterator_with_index(cc_pointer ptr, int, int) : m_ptr_to_cc(ptr),
|
||||
m_index(0)
|
||||
{
|
||||
if(!m_ptr_to_cc->is_used(m_index))
|
||||
{ increment(); }
|
||||
}
|
||||
|
||||
// Construction from raw pointer and for end().
|
||||
CC_iterator_with_index(cc_pointer ptr, size_type index) : m_ptr_to_cc(ptr),
|
||||
m_index(index)
|
||||
{}
|
||||
|
||||
// NB : in case empty container, begin == end == NULL.
|
||||
void increment()
|
||||
{
|
||||
// It's either pointing to end(), or valid.
|
||||
CGAL_assertion_msg(m_ptr_to_cc != NULL,
|
||||
"Incrementing a singular iterator or an empty container iterator ?");
|
||||
CGAL_assertion_msg(m_index < m_ptr_to_cc->capacity_,
|
||||
"Incrementing end() ?");
|
||||
|
||||
// If it's not end(), then it's valid, we can do ++.
|
||||
do
|
||||
{
|
||||
++m_index;
|
||||
}
|
||||
while ( m_index < m_ptr_to_cc->capacity_ &&
|
||||
(!m_ptr_to_cc->is_used(m_index)) );
|
||||
}
|
||||
|
||||
void decrement()
|
||||
{
|
||||
// It's either pointing to end(), or valid.
|
||||
CGAL_assertion_msg(m_ptr_to_cc != NULL,
|
||||
"Decrementing a singular iterator or an empty container iterator ?");
|
||||
CGAL_assertion_msg(m_index>0, "Decrementing begin() ?");
|
||||
|
||||
// If it's not begin(), then it's valid, we can do --.
|
||||
do
|
||||
{
|
||||
--m_index;
|
||||
}
|
||||
while ( !m_ptr_to_cc->is_used(m_index));
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Self & operator++()
|
||||
{ increment(); return *this; }
|
||||
|
||||
Self & operator--()
|
||||
{ decrement(); return *this; }
|
||||
|
||||
Self operator++(int) { Self tmp(*this); ++(*this); return tmp; }
|
||||
Self operator--(int) { Self tmp(*this); --(*this); return tmp; }
|
||||
|
||||
reference operator*() const { return ((*m_ptr_to_cc)[m_index]); }
|
||||
|
||||
pointer operator->() const { return &((*m_ptr_to_cc)[m_index]); }
|
||||
|
||||
// Can itself be used for bit-squatting.
|
||||
size_type for_compact_container() const
|
||||
{ return m_index; }
|
||||
void for_compact_container(size_type v)
|
||||
{ m_index=v; }
|
||||
|
||||
template<class ADSC,bool AC1,bool AC2>
|
||||
friend bool operator==(const CC_iterator_with_index<ADSC,AC1>&,
|
||||
const CC_iterator_with_index<ADSC,AC2>&);
|
||||
|
||||
template<class ADSC,bool AC1,bool AC2>
|
||||
friend bool operator!=(const CC_iterator_with_index<ADSC,AC1>&,
|
||||
const CC_iterator_with_index<ADSC,AC2>&);
|
||||
};
|
||||
|
||||
template < class DSC, bool Const1, bool Const2 >
|
||||
inline
|
||||
bool operator==(const CC_iterator_with_index<DSC, Const1> &rhs,
|
||||
const CC_iterator_with_index<DSC, Const2> &lhs)
|
||||
{
|
||||
return rhs.m_ptr_to_cc == lhs.m_ptr_to_cc &&
|
||||
rhs.m_index == lhs.m_index;
|
||||
}
|
||||
|
||||
template < class DSC, bool Const1, bool Const2 >
|
||||
inline
|
||||
bool operator!=(const CC_iterator_with_index<DSC, Const1> &rhs,
|
||||
const CC_iterator_with_index<DSC, Const2> &lhs)
|
||||
{
|
||||
return rhs.m_ptr_to_cc != lhs.m_ptr_to_cc ||
|
||||
rhs.m_index != lhs.m_index;
|
||||
}
|
||||
|
||||
// Comparisons with NULL are part of CGAL's Handle concept...
|
||||
/* template < class DSC, bool Const >
|
||||
inline
|
||||
bool operator==(const CC_iterator_with_index<DSC, Const> &rhs,
|
||||
Nullptr_t CGAL_assertion_code(n))
|
||||
{
|
||||
CGAL_assertion( n == NULL);
|
||||
return rhs.m_index == 0;
|
||||
}
|
||||
|
||||
template < class DSC, bool Const >
|
||||
inline
|
||||
bool operator!=(const CC_iterator_with_index<DSC, Const> &rhs,
|
||||
Nullptr_t CGAL_assertion_code(n))
|
||||
{
|
||||
CGAL_assertion( n == NULL);
|
||||
return rhs.m_index != 0;
|
||||
}*/
|
||||
|
||||
} // namespace internal
|
||||
|
||||
} //namespace CGAL
|
||||
|
||||
namespace std
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
#ifndef CGAL_COMPACT_CONTAINER_WITH_INDEX_3_H
|
||||
#define CGAL_COMPACT_CONTAINER_WITH_INDEX_3_H
|
||||
|
||||
#include <CGAL/Compact_container_with_index.h>
|
||||
#include <CGAL/Compact_container.h>
|
||||
#include <deque>
|
||||
#include <bitset>
|
||||
|
||||
|
|
@ -65,6 +65,228 @@
|
|||
|
||||
namespace CGAL {
|
||||
|
||||
template < class T, class Allocator_, class Increment_policy, class IndexType>
|
||||
class Compact_container_with_index_2;
|
||||
|
||||
template<unsigned int k>
|
||||
struct Multiply_by_two_policy_for_cc_with_size
|
||||
{
|
||||
static const unsigned int first_block_size = k;
|
||||
|
||||
template<typename Compact_container>
|
||||
static void increase_size(Compact_container& cc)
|
||||
{ cc.block_size=cc.capacity_; }
|
||||
};
|
||||
|
||||
template<unsigned int k>
|
||||
struct Constant_size_policy_for_cc_with_size
|
||||
{
|
||||
static const unsigned int first_block_size = k;
|
||||
|
||||
template<typename Compact_container>
|
||||
static void increase_size(Compact_container& /*cc*/)
|
||||
{}
|
||||
};
|
||||
|
||||
// The traits class describes the way to access the size_type.
|
||||
// It can be specialized.
|
||||
template < class T, class size_type >
|
||||
struct Compact_container_with_index_traits {
|
||||
static size_type size_t(const T &t)
|
||||
{ return t.for_compact_container(); }
|
||||
static void set_size_t(T &t, size_type v)
|
||||
{ t.for_compact_container(v); }
|
||||
};
|
||||
|
||||
namespace internal {
|
||||
|
||||
// **********************************************************************
|
||||
// specialization if we use index: in this case, an iterator use one more
|
||||
// data member of type size_type: memory footprint is more important than
|
||||
// iterator without index. However such iterator is not supposed to be used
|
||||
// in function parameters, to store handles through elements...
|
||||
// We must use indices for that.
|
||||
template < class DSC, bool Const >
|
||||
class CC_iterator_with_index
|
||||
{
|
||||
typedef typename DSC::iterator iterator;
|
||||
typedef CC_iterator_with_index<DSC, Const> Self;
|
||||
|
||||
friend class CC_iterator_with_index<DSC, true>;
|
||||
friend class CC_iterator_with_index<DSC, false>;
|
||||
|
||||
public:
|
||||
typedef typename DSC::value_type value_type;
|
||||
typedef typename DSC::size_type size_type;
|
||||
typedef typename DSC::difference_type difference_type;
|
||||
typedef typename boost::mpl::if_c< Const, const value_type*,
|
||||
value_type*>::type pointer;
|
||||
typedef typename boost::mpl::if_c< Const, const value_type&,
|
||||
value_type&>::type reference;
|
||||
typedef std::bidirectional_iterator_tag iterator_category;
|
||||
|
||||
typedef typename boost::mpl::if_c< Const, const DSC*, DSC*>::type
|
||||
cc_pointer;
|
||||
|
||||
// the initialization with NULL is required by our Handle concept.
|
||||
CC_iterator_with_index() : m_ptr_to_cc(NULL),
|
||||
m_index(0)
|
||||
{}
|
||||
|
||||
// Either a harmless copy-ctor,
|
||||
// or a conversion from iterator to const_iterator.
|
||||
CC_iterator_with_index (const iterator &it) : m_ptr_to_cc(it.m_ptr_to_cc),
|
||||
m_index(it.m_index)
|
||||
{}
|
||||
|
||||
// Same for assignment operator (otherwise MipsPro warns)
|
||||
CC_iterator_with_index & operator= (const iterator &it)
|
||||
{
|
||||
m_ptr_to_cc = it.m_ptr_to_cc;
|
||||
m_index = it.m_index;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Construction from NULL
|
||||
CC_iterator_with_index (Nullptr_t CGAL_assertion_code(n)) :
|
||||
m_ptr_to_cc(NULL),
|
||||
m_index(0)
|
||||
{ CGAL_assertion (n == NULL); }
|
||||
|
||||
operator size_type() const
|
||||
{ return m_index; }
|
||||
|
||||
size_type get_current() const
|
||||
{ return m_index; }
|
||||
|
||||
protected:
|
||||
void set_current(size_type dh)
|
||||
{ m_index = dh; }
|
||||
|
||||
protected:
|
||||
|
||||
template<class,class,class>
|
||||
friend class CGAL::Compact_container_with_index_2;
|
||||
|
||||
cc_pointer m_ptr_to_cc;
|
||||
size_type m_index;
|
||||
|
||||
// For begin()
|
||||
CC_iterator_with_index(cc_pointer ptr, int, int) : m_ptr_to_cc(ptr),
|
||||
m_index(0)
|
||||
{
|
||||
if(!m_ptr_to_cc->is_used(m_index))
|
||||
{ increment(); }
|
||||
}
|
||||
|
||||
// Construction from raw pointer and for end().
|
||||
CC_iterator_with_index(cc_pointer ptr, size_type index) : m_ptr_to_cc(ptr),
|
||||
m_index(index)
|
||||
{}
|
||||
|
||||
// NB : in case empty container, begin == end == NULL.
|
||||
void increment()
|
||||
{
|
||||
// It's either pointing to end(), or valid.
|
||||
CGAL_assertion_msg(m_ptr_to_cc != NULL,
|
||||
"Incrementing a singular iterator or an empty container iterator ?");
|
||||
CGAL_assertion_msg(m_index < m_ptr_to_cc->capacity_,
|
||||
"Incrementing end() ?");
|
||||
|
||||
// If it's not end(), then it's valid, we can do ++.
|
||||
do
|
||||
{
|
||||
++m_index;
|
||||
}
|
||||
while ( m_index < m_ptr_to_cc->capacity_ &&
|
||||
(!m_ptr_to_cc->is_used(m_index)) );
|
||||
}
|
||||
|
||||
void decrement()
|
||||
{
|
||||
// It's either pointing to end(), or valid.
|
||||
CGAL_assertion_msg(m_ptr_to_cc != NULL,
|
||||
"Decrementing a singular iterator or an empty container iterator ?");
|
||||
CGAL_assertion_msg(m_index>0, "Decrementing begin() ?");
|
||||
|
||||
// If it's not begin(), then it's valid, we can do --.
|
||||
do
|
||||
{
|
||||
--m_index;
|
||||
}
|
||||
while ( !m_ptr_to_cc->is_used(m_index));
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Self & operator++()
|
||||
{ increment(); return *this; }
|
||||
|
||||
Self & operator--()
|
||||
{ decrement(); return *this; }
|
||||
|
||||
Self operator++(int) { Self tmp(*this); ++(*this); return tmp; }
|
||||
Self operator--(int) { Self tmp(*this); --(*this); return tmp; }
|
||||
|
||||
reference operator*() const { return ((*m_ptr_to_cc)[m_index]); }
|
||||
|
||||
pointer operator->() const { return &((*m_ptr_to_cc)[m_index]); }
|
||||
|
||||
// Can itself be used for bit-squatting.
|
||||
size_type for_compact_container() const
|
||||
{ return m_index; }
|
||||
void for_compact_container(size_type v)
|
||||
{ m_index=v; }
|
||||
|
||||
template<class ADSC,bool AC1,bool AC2>
|
||||
friend bool operator==(const CC_iterator_with_index<ADSC,AC1>&,
|
||||
const CC_iterator_with_index<ADSC,AC2>&);
|
||||
|
||||
template<class ADSC,bool AC1,bool AC2>
|
||||
friend bool operator!=(const CC_iterator_with_index<ADSC,AC1>&,
|
||||
const CC_iterator_with_index<ADSC,AC2>&);
|
||||
};
|
||||
|
||||
template < class DSC, bool Const1, bool Const2 >
|
||||
inline
|
||||
bool operator==(const CC_iterator_with_index<DSC, Const1> &rhs,
|
||||
const CC_iterator_with_index<DSC, Const2> &lhs)
|
||||
{
|
||||
return rhs.m_ptr_to_cc == lhs.m_ptr_to_cc &&
|
||||
rhs.m_index == lhs.m_index;
|
||||
}
|
||||
|
||||
template < class DSC, bool Const1, bool Const2 >
|
||||
inline
|
||||
bool operator!=(const CC_iterator_with_index<DSC, Const1> &rhs,
|
||||
const CC_iterator_with_index<DSC, Const2> &lhs)
|
||||
{
|
||||
return rhs.m_ptr_to_cc != lhs.m_ptr_to_cc ||
|
||||
rhs.m_index != lhs.m_index;
|
||||
}
|
||||
|
||||
// Comparisons with NULL are part of CGAL's Handle concept...
|
||||
/* template < class DSC, bool Const >
|
||||
inline
|
||||
bool operator==(const CC_iterator_with_index<DSC, Const> &rhs,
|
||||
Nullptr_t CGAL_assertion_code(n))
|
||||
{
|
||||
CGAL_assertion( n == NULL);
|
||||
return rhs.m_index == 0;
|
||||
}
|
||||
|
||||
template < class DSC, bool Const >
|
||||
inline
|
||||
bool operator!=(const CC_iterator_with_index<DSC, Const> &rhs,
|
||||
Nullptr_t CGAL_assertion_code(n))
|
||||
{
|
||||
CGAL_assertion( n == NULL);
|
||||
return rhs.m_index != 0;
|
||||
}*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
template<class Index_type>
|
||||
class Index_for_cc_with_index
|
||||
{
|
||||
|
|
@ -237,6 +459,7 @@ public:
|
|||
std::swap(alloc, c.alloc);
|
||||
std::swap(capacity_, c.capacity_);
|
||||
std::swap(size_, c.size_);
|
||||
std::swap(last_index, c.last_index);
|
||||
std::swap(block_size, c.block_size);
|
||||
std::swap(free_list, c.free_list);
|
||||
std::swap(used, c.used);
|
||||
|
|
@ -299,6 +522,7 @@ public:
|
|||
if(size_==capacity_)
|
||||
{ allocate_new_block(); }
|
||||
ret=size_;
|
||||
++last_index;
|
||||
}
|
||||
|
||||
T& e = operator[](ret);
|
||||
|
|
@ -322,6 +546,7 @@ public:
|
|||
if(size_==capacity_)
|
||||
{ allocate_new_block(); }
|
||||
ret=size_;
|
||||
++last_index;
|
||||
}
|
||||
|
||||
T& e = operator[](ret);
|
||||
|
|
@ -355,8 +580,10 @@ public:
|
|||
#ifndef CGAL_NO_ASSERTIONS
|
||||
std::memset(&e, 0, sizeof(T));
|
||||
#endif
|
||||
if(x<size_-1) // If we erase the last element, it is not pushed on the free list.
|
||||
if(x<last_index-1) // If we erase the last element, it is not pushed on the free list.
|
||||
{ put_on_free_list(x); }
|
||||
else { --last_index; }
|
||||
used[x]=false;
|
||||
--size_;
|
||||
}
|
||||
|
||||
|
|
@ -474,12 +701,15 @@ private:
|
|||
block_size = Incr_policy::first_block_size;
|
||||
capacity_ = 0;
|
||||
size_ = 0;
|
||||
last_index = 0;
|
||||
last_index = 0;
|
||||
all_items = nullptr;
|
||||
}
|
||||
|
||||
allocator_type alloc;
|
||||
size_type capacity_;
|
||||
size_type size_;
|
||||
size_type last_index;
|
||||
size_type block_size;
|
||||
std::deque<size_type> free_list;
|
||||
std::vector<bool> used;
|
||||
|
|
|
|||
Loading…
Reference in New Issue