13 #include "inmost_common.h"
18 #define __VOLATILE volatile
51 template<>
struct make_unsigned<long long> {
typedef unsigned long long type;};
52 template<>
struct make_unsigned<unsigned char> {
typedef unsigned char type;};
53 template<>
struct make_unsigned<unsigned short> {
typedef unsigned short type;};
54 template<>
struct make_unsigned<unsigned int> {
typedef unsigned int type;};
55 template<>
struct make_unsigned<unsigned long> {
typedef unsigned long type;};
56 template<>
struct make_unsigned<unsigned long long> {
typedef unsigned long long type;};
59 #if defined(PACK_ARRAY)
60 #pragma pack(push,r1,4)
65 template<
typename element>
69 typedef unsigned size_type;
71 template<
typename etype>
77 typedef etype * pointer;
78 typedef etype & reference;
79 typedef etype value_type;
80 typedef ptrdiff_t difference_type;
81 typedef std::random_access_iterator_tag iterator_category;
87 _iterator & operator -=(
size_t n) { e-=n;
return *
this; }
89 _iterator & operator +=(
size_t n) { e+=n;
return *
this; }
90 _iterator & operator ++(){ ++e;
return *
this;}
92 _iterator & operator --(){ --e;
return *
this; }
94 ptrdiff_t operator -(
const _iterator & other)
const {
return e-other.e;}
95 etype & operator *()
const {
return *e; }
96 etype * operator ->()
const {
return e; }
98 bool operator ==(
const _iterator & other)
const {
return e == other.e;}
99 bool operator !=(
const _iterator & other)
const {
return e != other.e;}
100 bool operator <(
const _iterator & other)
const {
return e < other.e;}
101 bool operator >(
const _iterator & other)
const {
return e > other.e;}
102 bool operator <=(
const _iterator & other)
const {
return e <= other.e;}
103 bool operator >=(
const _iterator & other)
const {
return e >= other.e;}
104 operator void *()
const {
return static_cast<void *
> (e);}
108 template<
typename etype>
114 typedef etype * pointer;
115 typedef etype & reference;
116 typedef etype value_type;
117 typedef ptrdiff_t difference_type;
118 typedef std::random_access_iterator_tag iterator_category;
132 etype & operator *()
const {
return *e; }
133 etype * operator ->()
const {
return e; }
141 operator void *()
const {
return static_cast<void *
> (e);}
151 __INLINE
static size_type growth_formula(size_type future_size)
153 uenum v =
static_cast<uenum
>(future_size);
163 return static_cast<size_type
>(v);
166 static element * realloc(element * ptr, size_type old_size, size_type new_size)
168 size_type gf = growth_formula(new_size);
169 if( gf != growth_formula(old_size) )
171 element * tmp =
new element[gf];
172 #if defined(DEBUGMEM)
173 if( tmp == NULL ) {std::cout << __FILE__ <<
":" << __LINE__ <<
"allocation returns NULL\n";}
175 std::copy(ptr,ptr+std::min(old_size,new_size),tmp);
182 static element * alloc(size_type init_size)
184 element * tmp =
new element[growth_formula(init_size)];
185 #if defined(DEBUGMEM)
186 if( tmp == NULL ) {std::cout << __FILE__ <<
":" << __LINE__ <<
"allocation returns NULL\n";}
191 static element * copy(
const element * ibeg,
const element * iend, element * obeg)
193 if (std::less<const element *>()(ibeg, obeg))
195 obeg += (iend - ibeg);
196 std::copy_backward(ibeg, iend, obeg);
198 }
else return std::copy(ibeg, iend, obeg);
201 __INLINE element * data() {
return m_arr;}
202 __INLINE
const element * data()
const {
return m_arr;}
203 array() {m_arr = NULL; m_size = 0;}
204 array(size_type n,element c = element())
208 std::fill(m_arr,m_arr+m_size,c);
210 template<
class InputIterator>
211 array(InputIterator first, InputIterator last)
213 m_size =
static_cast<size_type
>(std::distance(first,last));
214 m_arr = alloc(m_size);
215 std::copy(first,last,m_arr);
217 array(
const array & other)
219 m_size = other.m_size;
222 m_arr = alloc(m_size);
223 std::copy(other.m_arr,other.m_arr+other.m_size,m_arr);
228 __INLINE
const element & operator [] (size_type n)
const
233 __INLINE element & operator [] (size_type n)
238 __INLINE
const element & at (size_type n)
const
243 __INLINE element & at (size_type n)
248 __INLINE element & at_safe (size_type n)
250 if( n >= m_size ) resize(n+1);
253 array & operator =(array
const & other)
259 if( other.m_arr != NULL )
261 m_size = other.m_size;
262 m_arr = alloc(m_size);
263 std::copy(other.m_arr,other.m_arr+other.m_size,m_arr);
268 void push_back(
const element & e)
270 m_arr = realloc(m_arr,m_size,m_size+1);
275 assert(m_arr != NULL);
278 m_arr = realloc(m_arr,m_size,m_size-1);
283 __INLINE element & back()
285 assert(m_arr != NULL);
287 return m_arr[m_size-1];
289 __INLINE
const element & back()
const
291 assert(m_arr != NULL);
293 return m_arr[m_size-1];
295 __INLINE element & front()
297 assert(m_arr != NULL);
301 __INLINE
const element & front()
const
303 assert(m_arr != NULL);
307 __INLINE size_type capacity() {
return growth_formula(m_size); }
308 __INLINE
bool empty()
const {
if( m_size )
return false;
return true; }
309 void resize(size_type n, element c = element() )
311 size_type oldsize = m_size;
315 m_arr = realloc(m_arr,oldsize,m_size);
316 if( oldsize < m_size ) std::fill(m_arr+oldsize,m_arr+m_size,c);
320 __INLINE size_type size()
const {
return m_size;}
321 __INLINE size_type capacity()
const {
return growth_formula(m_size);}
324 if( m_arr )
delete [] m_arr;
328 void swap(array<element> & other)
330 element * t_m_arr = m_arr;
331 size_type t_m_size = m_size;
333 m_size = other.m_size;
334 other.m_arr = t_m_arr;
335 other.m_size = t_m_size;
337 __INLINE iterator begin() {
return m_arr; }
338 __INLINE iterator end() {
return m_arr+m_size; }
339 __INLINE const_iterator begin()
const {
return m_arr; }
340 __INLINE const_iterator end()
const {
return m_arr+m_size; }
341 __INLINE reverse_iterator rbegin() {
return reverse_iterator(m_arr+m_size-1); }
342 __INLINE reverse_iterator rend() {
return reverse_iterator(m_arr-1); }
343 __INLINE const_reverse_iterator rbegin()
const {
return const_reverse_iterator(m_arr+m_size-1); }
344 __INLINE const_reverse_iterator rend()
const {
return const_reverse_iterator(m_arr-1); }
345 iterator erase(iterator pos)
347 ptrdiff_t d = pos-begin();
348 ptrdiff_t s = iterator(m_arr+(m_size-1))-pos;
352 if( s ) copy(m_arr+d+1, m_arr+d+1+s, m_arr+d);
353 m_arr = realloc(m_arr, m_size+1, m_size);
358 iterator erase(iterator b, iterator e)
360 ptrdiff_t d = b-begin();
361 ptrdiff_t s = end()-e;
366 if( s ) copy(m_arr+d+1,m_arr+d+1+s,m_arr+d);
367 m_arr = realloc(m_arr,m_size+n,m_size);
373 iterator insert(iterator pos,
const element & x)
375 if(
static_cast<void *
>(pos) == NULL)
377 assert(m_arr == NULL);
379 m_arr = alloc(m_size);
385 ptrdiff_t d = pos-begin();
386 ptrdiff_t s = end()-pos;
387 m_arr = realloc(m_arr,m_size,m_size+1);
388 if( s ) copy(m_arr+d,m_arr+d+s,m_arr+d+1);
394 void insert(iterator pos, size_type n,
const element & x)
398 if(
static_cast<void *
>(pos) == NULL)
400 assert(m_arr == NULL);
403 std::fill(m_arr,m_arr+m_size,x);
407 ptrdiff_t d = pos-begin();
408 ptrdiff_t s = end()-pos;
409 m_arr = realloc(m_arr,m_size,m_size+n);
411 if( s ) copy(m_arr+d,m_arr+d+s,m_arr+d+n);
412 std::fill(m_arr+d,m_arr+d+n,x);
416 template <
class InputIterator>
417 void insert(iterator pos, InputIterator first, InputIterator last)
419 size_type n =
static_cast<size_type
>(std::distance(first,last));
422 if(
static_cast<void *
>(pos) == NULL)
424 assert(m_arr == NULL);
427 std::copy(first,last,m_arr);
431 ptrdiff_t d = pos-begin();
432 ptrdiff_t s = end()-pos;
433 m_arr = realloc(m_arr,m_size,m_size+n);
435 if( s ) copy(m_arr+d,m_arr+d+s,m_arr+d+n);
436 std::copy(first,last,m_arr+d);
440 template <
class InputIterator>
441 void replace(iterator m_first, iterator m_last, InputIterator first, InputIterator last)
443 assert( m_size >= 0 );
444 size_type n =
static_cast<size_type
>(std::distance(first,last));
445 if(
static_cast<void *
>(m_first) == NULL && m_arr == NULL)
447 assert(m_arr == NULL);
450 std::copy(first,last,m_arr);
454 ptrdiff_t q = m_last-m_first;
455 ptrdiff_t d = m_first-iterator(m_arr);
456 ptrdiff_t s = iterator(m_arr+m_size)-m_last;
459 m_arr = realloc(m_arr,m_size,m_size+
static_cast<size_type
>(n-q));
460 m_size+=
static_cast<size_type
>(n-q);
461 if( s ) copy(m_arr+d+q,m_arr+d+q+s,m_arr+d+n);
463 std::copy(first,last,m_arr+d);
466 template <
class InputIterator>
467 void assign(InputIterator first, InputIterator last)
469 replace(begin(),end(),first,last);
471 template<
class>
friend class shell;
473 #if defined(PACK_ARRAY)
476 template<
typename element>
480 typedef typename array<element>::size_type size_type;
481 template<
typename dtype>
487 typedef dtype * pointer;
488 typedef dtype & reference;
489 typedef dtype value_type;
490 typedef ptrdiff_t difference_type;
491 typedef std::random_access_iterator_tag iterator_category;
497 _iterator & operator -=(
size_t n) { e-=n;
return *
this; }
499 _iterator & operator +=(
size_t n) { e+=n;
return *
this; }
500 _iterator & operator ++(){ ++e;
return *
this;}
502 _iterator & operator --(){ --e;
return *
this; }
504 ptrdiff_t operator -(
const _iterator & other)
const {
return e-other.e;}
505 dtype & operator *()
const {
return *e; }
506 dtype * operator ->()
const {
return e; }
508 bool operator ==(
const _iterator & other)
const {
return e == other.e;}
509 bool operator !=(
const _iterator & other)
const {
return e != other.e;}
510 bool operator <(
const _iterator & other)
const {
return e < other.e;}
511 bool operator >(
const _iterator & other)
const {
return e > other.e;}
512 bool operator <=(
const _iterator & other)
const {
return e <= other.e;}
513 bool operator >=(
const _iterator & other)
const {
return e >= other.e;}
514 operator void *()
const {
return static_cast<void *
> (e);}
518 template<
typename dtype>
524 typedef dtype * pointer;
525 typedef dtype & reference;
526 typedef dtype value_type;
527 typedef ptrdiff_t difference_type;
528 typedef std::random_access_iterator_tag iterator_category;
542 dtype & operator *()
const {
return *e; }
543 dtype * operator ->()
const {
return e; }
551 operator void *()
const {
return static_cast<void *
> (e);}
558 element * local_link;
559 size_type local_size;
562 __INLINE element * data() {
return *m_arr;}
563 __INLINE
const element * data()
const {
return *m_arr;}
564 shell() :m_arr(NULL), m_size(NULL), local_link(NULL), local_size(0), fixed(false) { }
565 shell(array<element> & arr)
566 :m_arr(&arr.m_arr), m_size(&arr.m_size), local_link(NULL), local_size(0), fixed(false) {}
567 shell(element * link, size_type size)
568 :m_arr(&local_link), m_size(&local_size), local_link(NULL),local_size(0), fixed(true)
573 shell(
const shell & other)
574 :m_arr(&local_link), m_size(&local_size), local_link(NULL), local_size(0),fixed(other.fixed)
578 *m_size = *other.m_size;
579 *m_arr = *other.m_arr;
583 m_size = other.m_size;
590 __INLINE
const element & operator [] (size_type n)
const
592 assert(n < *m_size );
593 return *((*m_arr)+n);
595 __INLINE element & operator [] (size_type n)
597 assert(n < *m_size );
598 return *((*m_arr)+n);
600 __INLINE
const element & at (size_type n)
const
602 assert(n < *m_size );
603 return *((*m_arr)+n);
605 __INLINE element & at (size_type n)
607 assert(n < *m_size );
608 return *((*m_arr)+n);
610 shell & operator =(shell
const & other)
615 m_size = &local_size;
617 *m_size = *other.m_size;
618 *m_arr = *other.m_arr;
622 m_size = other.m_size;
627 void push_back(
const element & e)
630 *m_arr = array<element>::realloc(*m_arr,*m_size,(*m_size)+1);
631 (*m_arr)[(*m_size)++] = e;
636 assert((*m_arr) != NULL);
639 *m_arr = array<element>::realloc(*m_arr,*m_size,(*m_size)-1);
644 __INLINE element & back()
646 assert(*m_arr != NULL);
647 assert(*m_size > 0 );
648 return (*m_arr)[(*m_size)-1];
650 __INLINE
const element & back()
const
652 assert(*m_arr != NULL);
653 assert(*m_size > 0 );
654 return (*m_arr)[(*m_size)-1];
656 __INLINE element & front()
658 assert(*m_arr != NULL);
659 assert(*m_size > 0 );
662 __INLINE
const element & front()
const
664 assert(*m_arr != NULL);
665 assert(*m_size > 0 );
668 __INLINE size_type capacity() {
return array<element>::growth_formula(*m_size); }
669 __INLINE
bool empty()
const {
if( *m_size )
return false;
return true; }
670 void resize(size_type n, element c = element() )
673 size_type oldsize = *m_size;
677 *m_arr = array<element>::realloc(*m_arr,oldsize,*m_size);
678 if( oldsize < *m_size ) std::fill((*m_arr)+oldsize,(*m_arr)+(*m_size),c);
682 __INLINE size_type size()
const {
return *m_size;}
686 if( *m_arr )
delete [] *m_arr;
690 void swap(shell<element> & other)
692 element * t_m_arr = *m_arr;
693 size_type t_m_size = *m_size;
694 *m_arr = *other.m_arr;
695 *m_size = *other.m_size;
696 *other.m_arr = t_m_arr;
697 *other.m_size = t_m_size;
699 __INLINE iterator begin() {
return *m_arr; }
700 __INLINE iterator end() {
return (*m_arr)+(*m_size); }
701 __INLINE const_iterator begin()
const {
return (*m_arr); }
702 __INLINE const_iterator end()
const {
return (*m_arr)+(*m_size); }
703 __INLINE reverse_iterator rbegin() {
return reverse_iterator((*m_arr)+(*m_size)-1); }
704 __INLINE reverse_iterator rend() {
return reverse_iterator((*m_arr)-1); }
705 __INLINE const_reverse_iterator rbegin()
const {
return const_reverse_iterator((*m_arr)+(*m_size)-1); }
706 __INLINE const_reverse_iterator rend()
const {
return const_reverse_iterator((*m_arr)-1); }
707 iterator erase(iterator pos)
710 ptrdiff_t d = pos-begin();
711 ptrdiff_t s = iterator((*m_arr)+(*m_size)-1)-pos;
715 if( s ) array<element>::copy((*m_arr)+d+1, (*m_arr)+d+1+s, (*m_arr)+d);
716 *m_arr = array<element>::realloc(*m_arr, (*m_size)+1, *m_size);
721 iterator erase(iterator b, iterator e)
724 ptrdiff_t d = b-begin();
725 ptrdiff_t s = end()-e;
730 if( s ) array<element>::copy((*m_arr)+d+1,(*m_arr)+d+1+s,(*m_arr)+d);
731 *m_arr = array<element>::realloc(*m_arr,(*m_size)+n,*m_size);
737 iterator insert(iterator pos,
const element & x)
740 if(
static_cast<void *
>(pos) == NULL )
742 assert((*m_arr) == NULL);
744 *m_arr = array<element>::alloc(*m_size);
750 ptrdiff_t d = pos-begin();
751 ptrdiff_t s = end()-pos;
752 *m_arr = array<element>::realloc(*m_arr,*m_size,(*m_size)+1);
754 if( s ) array<element>::copy((*m_arr)+d,(*m_arr)+d+s,(*m_arr)+d+1);
759 void insert(iterator pos, size_type n,
const element & x)
764 if(
static_cast<void *
>(pos) == NULL)
766 assert((*m_arr) == NULL);
767 *m_arr = array<element>::alloc(n);
769 std::fill(*m_arr,(*m_arr)+(*m_size),x);
773 ptrdiff_t d = pos-iterator(*m_arr);
774 ptrdiff_t s = iterator((*m_arr)+(*m_size))-pos;
775 *m_arr = array<element>::realloc(*m_arr,*m_size,(*m_size)+n);
777 if( s ) array<element>::copy((*m_arr)+d,(*m_arr)+d+s,(*m_arr)+d+n);
778 std::fill((*m_arr)+d,(*m_arr)+d+n,x);
782 template <
class InputIterator>
783 void insert(iterator pos, InputIterator first, InputIterator last)
786 size_type n =
static_cast<size_type
>(std::distance(first,last));
789 if(
static_cast<void *
>(pos) == NULL)
791 assert((*m_arr) == NULL);
792 *m_arr = array<element>::alloc(n);
794 std::copy(first,last,*m_arr);
798 ptrdiff_t d = pos-iterator(*m_arr);
799 ptrdiff_t s = iterator((*m_arr)+(*m_size))-pos;
800 *m_arr = array<element>::realloc(*m_arr,*m_size,(*m_size)+n);
802 if( s ) array<element>::copy((*m_arr)+d,(*m_arr)+d+s,(*m_arr)+d+n);
803 std::copy(first,last,(*m_arr)+d);
807 template <
class InputIterator>
808 void replace(iterator m_first, iterator m_last, InputIterator first, InputIterator last)
810 size_type n =
static_cast<size_type
>(std::distance(first,last));
811 if(
static_cast<void *
>(m_first) == NULL)
813 assert((*m_arr)==NULL);
814 *m_arr = array<element>::alloc(n);
816 std::copy(first,last,*m_arr);
820 ptrdiff_t q = m_last-m_first;
821 ptrdiff_t d = m_first-iterator(*m_arr);
822 ptrdiff_t s = iterator((*m_arr)+(*m_size))-m_last;
825 *m_arr = array<element>::realloc(*m_arr,*m_size,(*m_size)+
static_cast<size_type
>(n-q));
826 (*m_size)+=
static_cast<size_type
>(n-q);
827 if( s ) array<element>::copy((*m_arr)+d+q,(*m_arr)+d+q+s,(*m_arr)+d+n);
829 std::copy(first,last,(*m_arr)+d);
832 template <
class InputIterator>
833 void assign(InputIterator first, InputIterator last)
835 replace(begin(),end(),first,last);
839 template<
typename IndType,
typename ValType>
843 typedef ValType * iterator;
844 typedef ValType
const * const_iterator;
847 IndType beg_index, end_index;
851 if (!empty())
delete [] (parray + beg_index);
853 end_index = beg_index;
858 IndType tmp = beg_index;
859 beg_index = other.beg_index;
860 other.beg_index = tmp;
862 end_index = other.end_index;
863 other.end_index = tmp;
866 ValType * tmp = parray;
867 parray = other.parray;
880 end_index = beg_index;
883 interval(IndType beg, IndType end, ValType c = ValType())
889 ValType * tmp =
new ValType[end_index-beg_index];
890 #if defined(DEBUGMEM)
891 if( tmp == NULL ) {std::cout << __FILE__ <<
":" << __LINE__ <<
"allocation returns NULL\n";}
894 assert(parray != NULL);
895 parray = parray - beg_index;
896 std::fill(parray+beg_index,parray+end_index,c);
902 beg_index = other.beg_index;
903 end_index = other.end_index;
904 if( beg_index != end_index )
906 ValType * tmp =
new ValType[end_index-beg_index];
907 #if defined(DEBUGMEM)
908 if( tmp == NULL ) {std::cout << __FILE__ <<
":" << __LINE__ <<
"allocation returns NULL\n";}
910 parray =
static_cast<ValType *
>(tmp);
911 assert(parray != NULL);
912 parray = parray - beg_index;
913 std::copy(other.parray+beg_index,other.parray+end_index,parray+beg_index);
926 beg_index = other.beg_index;
927 end_index = other.end_index;
928 if( beg_index != end_index )
930 ValType * tmp =
new ValType[end_index-beg_index];
931 #if defined(DEBUGMEM)
932 if( tmp == NULL ) {std::cout << __FILE__ <<
":" << __LINE__ <<
"allocation returns NULL\n";}
934 parray =
static_cast<ValType *
>(tmp);
935 assert(parray != NULL);
936 parray = parray - beg_index;
937 std::copy(other.parray+beg_index,other.parray+end_index,parray+beg_index);
942 ValType & at(IndType row)
944 assert(row >= beg_index);
945 assert(row < end_index);
948 const ValType & at(IndType row)
const
950 assert(row >= beg_index);
951 assert(row < end_index);
954 ValType & operator [](IndType row)
956 assert(row >= beg_index );
957 assert(row < end_index );
960 const ValType & operator [](IndType row)
const
962 assert(row >= beg_index );
963 assert(row < end_index );
966 void set_interval_beg(IndType beg)
968 IndType shift = beg-beg_index;
969 shift_interval(shift);
971 void set_interval_end(IndType end,
const ValType & c = ValType())
973 if( end == end_index )
return;
974 if( beg_index != end )
976 ValType * parray_new =
new ValType[end-beg_index];
977 #if defined(DEBUGMEM)
978 if( parray_new == NULL ) {std::cout << __FILE__ <<
":" << __LINE__ <<
"allocation returns NULL\n";}
980 assert(parray_new != NULL);
981 parray_new = parray_new - beg_index;
983 IndType mend = std::min(end,end_index);
987 std::copy(parray+beg_index,parray+mend,parray_new+beg_index);
990 if( mend < end ) std::fill(parray_new+mend,parray_new+end,c);
997 void shift_interval(IndType shift)
999 parray = parray + beg_index;
1002 parray = parray - beg_index;
1004 iterator begin() {
return parray+beg_index;}
1005 const_iterator begin()
const {
return parray+beg_index;}
1006 iterator end() {
return parray + end_index;}
1007 const_iterator end()
const {
return parray + end_index;}
1008 IndType get_interval_beg()
const {
return beg_index; }
1009 IndType get_interval_end()
const {
return end_index; }
1010 int size()
const {
return end_index - beg_index;}
1011 bool empty()
const {
return beg_index == end_index;}
1017 template<
typename element,
size_t base = 512>
1037 element & operator [](
size_t n)
1047 return next->operator [](n-base);
1050 const element & operator [](
size_t n)
const
1060 return next->operator [](n - base);
1065 if( ne == base && next )
1066 return base+next()->size();
1070 void resize(
size_t new_n,
const element & c = element())
1074 for (
size_t k = ne; k < new_n; ++k)
1090 for (
size_t k = ne; k < base; ++k)
1094 next->resize(new_n-base,c);
1100 template<
typename element,
int block_bits>
1104 typedef size_t size_type;
1107 static size_type
const block_bits_mask = (1 << (block_bits)) - 1;
1108 static size_type
const block_val = 1 << block_bits;
1109 static size_type
const block_size =
sizeof(element)*block_val;
1110 static size_type
const fwd_alloc_chunk_bits = 6;
1111 static size_type
const fwd_alloc_chunk_bits_mask = (1 << (fwd_alloc_chunk_bits))-1;
1112 static size_type
const fwd_alloc_chunk_val = 1 << fwd_alloc_chunk_bits;
1113 static size_type
const fwd_alloc_chunk_size =
sizeof(element *)*fwd_alloc_chunk_val;
1120 __INLINE size_type GetChunkNumber(size_type k)
const {
return static_cast<uenum
>(k) >> block_bits;}
1121 __INLINE size_type GetElementNumber(size_type k)
const {
return (k & block_bits_mask);}
1122 __INLINE element * access_block(size_type k) {
return chunks[GetChunkNumber(k)];}
1123 __INLINE
const element * access_block(size_type k)
const {
return chunks[GetChunkNumber(k)];}
1124 __INLINE element & access_element(size_type k) {
return access_block(k)[GetElementNumber(k)];}
1125 __INLINE
const element & access_element(size_type k)
const {
return access_block(k)[GetElementNumber(k)];}
1127 __INLINE element & operator [] (size_type i)
1130 return access_element(i);
1132 __INLINE
const element & operator [] (size_type i)
const
1135 return access_element(i);
1137 __INLINE element & at(size_type i)
1140 return access_element(i);
1142 __INLINE
const element & at(size_type i)
const
1145 return access_element(i);
1157 typedef element * pointer;
1158 typedef element & reference;
1159 typedef element value_type;
1160 typedef ptrdiff_t difference_type;
1161 typedef std::random_access_iterator_tag iterator_category;
1167 iterator & operator -=(size_type n) { pos-=n;
return *
this; }
1169 iterator & operator +=(size_type n) { pos+=n;
return *
this; }
1170 iterator & operator ++(){ ++pos;
return *
this;}
1172 iterator & operator --(){ --pos;
return *
this; }
1174 ptrdiff_t operator -(
const iterator & other)
const {
return pos-other.pos;}
1175 element & operator *()
const {
return link->at(pos); }
1176 element * operator ->()
const {
return &link->at(pos); }
1177 iterator & operator =(
iterator const & other) { link = other.link; pos = other.pos;
return *
this; }
1178 bool operator ==(
const iterator & other)
const { assert(link == other.link);
return pos == other.pos;}
1179 bool operator !=(
const iterator & other)
const { assert(link == other.link);
return pos != other.pos;}
1180 bool operator <(
const iterator & other)
const { assert(link == other.link);
return pos < other.pos;}
1181 bool operator >(
const iterator & other)
const { assert(link == other.link);
return pos > other.pos;}
1182 bool operator <=(
const iterator & other)
const { assert(link == other.link);
return pos <= other.pos;}
1183 bool operator >=(
const iterator & other)
const { assert(link == other.link);
return pos >= other.pos;}
1192 typedef element * pointer;
1193 typedef element & reference;
1194 typedef element value_type;
1195 typedef ptrdiff_t difference_type;
1196 typedef std::random_access_iterator_tag iterator_category;
1202 const_iterator & operator -=(size_type n) { pos-=n;
return *
this; }
1204 const_iterator & operator +=(size_type n) { pos+=n;
return *
this; }
1209 ptrdiff_t operator -(
const const_iterator & other)
const {
return pos-other.pos;}
1210 const element & operator *()
const {
return link->at(pos); }
1211 const element * operator ->()
const {
return &link->at(pos); }
1213 bool operator ==(
const const_iterator & other)
const { assert(link == other.link);
return pos == other.pos;}
1214 bool operator !=(
const const_iterator & other)
const { assert(link == other.link);
return pos != other.pos;}
1215 bool operator <(
const const_iterator & other)
const { assert(link == other.link);
return pos < other.pos;}
1216 bool operator >(
const const_iterator & other)
const { assert(link == other.link);
return pos > other.pos;}
1217 bool operator <=(
const const_iterator & other)
const { assert(link == other.link);
return pos <= other.pos;}
1218 bool operator >=(
const const_iterator & other)
const { assert(link == other.link);
return pos >= other.pos;}
1221 void inner_resize(size_type new_size)
1223 size_type oldnchunks2 = (
static_cast<uenum
>(m_size) >> block_bits) + ( (m_size & block_bits_mask) ? 1 : 0);
1224 size_type oldn = (
static_cast<uenum
>(oldnchunks2) >> fwd_alloc_chunk_bits) + ( (oldnchunks2 & fwd_alloc_chunk_bits_mask) ? 1 : 0);
1225 size_type newnchunks2 = (
static_cast<uenum
>(new_size) >> block_bits) + ( (new_size & block_bits_mask)? 1 : 0);
1226 size_type newn = (
static_cast<uenum
>(newnchunks2) >> fwd_alloc_chunk_bits) + ( (newnchunks2 & fwd_alloc_chunk_bits_mask) ? 1 : 0);
1227 for(size_type q = newnchunks2; q < oldnchunks2; q++)
1229 assert(chunks[q] != NULL);
1230 delete [] chunks[q];
1236 chunks.resize(fwd_alloc_chunk_size*newn);
1240 for(size_type q = oldnchunks2; q < newnchunks2; q++)
1242 assert(chunks[q] == NULL);
1243 chunks[q] =
new element[block_size/
sizeof(element)];
1244 #if defined(DEBUGMEM)
1245 if( chunks[q] == NULL ) {std::cout << __FILE__ <<
":" << __LINE__ <<
"allocation returns NULL\n";}
1247 assert(chunks[q] != NULL);
1253 size_type capacity()
const
1255 size_type chunks = ((
static_cast<uenum
>(m_size)>>block_bits) + ((m_size & block_bits_mask)? 1 : 0));
1256 return chunks*block_val;
1258 size_type size()
const {
return m_size;}
1259 bool empty()
const {
return size() == 0;}
1262 size_type cend = (
static_cast<uenum
>(m_size) >> block_bits) + ((m_size & block_bits_mask)? 1 : 0);
1263 for(size_type q = 0; q < cend; q++)
1266 delete [] chunks[q];
1276 chunk_array(
const chunk_array & other)
1279 inner_resize(other.size());
1280 for(size_type k = 0; k < other.size(); k++)
1281 new(&access_element(k)) element(other.access_element(k));
1282 m_size = other.size();
1284 chunk_array & operator =(chunk_array
const & other)
1286 if(
this != &other )
1289 inner_resize(other.size());
1290 for(size_type k = 0; k < other.size(); k++)
1291 access_element(k) = other.access_element(k);
1292 m_size = other.size();
1301 element & front() { assert(!empty());
return access_element(0);}
1302 element & back() { assert(!empty());
return access_element(size()-1);}
1303 const element & front()
const { assert(!empty());
return access_element(0);}
1304 const element & back()
const { assert(!empty());
return access_element(size()-1);}
1308 inner_resize(m_size-1);
1311 void push_back(
const element & e)
1313 inner_resize(m_size+1);
1314 access_element(m_size) = e;
1317 void resize(size_type n,
const element & e = element())
1320 for(size_type k = m_size; k < n; k++)
1321 access_element(k) = element(e);
1325 iterator erase(iterator pos)
1327 iterator it = pos, jt = it++;
1328 while(it != end()) (*jt++) = (*it++);
1329 inner_resize(m_size-1);
1334 iterator begin() {
return iterator(
this,0);}
1335 iterator end() {
return iterator(
this,m_size);}
1337 const_iterator begin()
const {
return const_iterator(
this,0);}
1338 const_iterator end()
const {
return const_iterator(
this,m_size);}
1342 template<
int block_bits>
1346 typedef size_t size_type;
1349 static size_type
const block_bits_mask = (1 << (block_bits)) - 1;
1350 static size_type
const block_val = 1 << block_bits;
1351 static size_type
const block_size =
sizeof(char)*block_val;
1352 static size_type
const fwd_alloc_chunk_bits = 6;
1353 static size_type
const fwd_alloc_chunk_bits_mask = (1 << (fwd_alloc_chunk_bits))-1;
1354 static size_type
const fwd_alloc_chunk_val = 1 << fwd_alloc_chunk_bits;
1355 static size_type
const fwd_alloc_chunk_size =
sizeof(
char *)*fwd_alloc_chunk_val;
1358 size_type record_size;
1361 __INLINE size_type GetChunkNumber(size_type k)
const {
return static_cast<uenum
>(k) >> block_bits;}
1362 __INLINE size_type GetElementNumber(size_type k)
const {
return (k & block_bits_mask) * record_size;}
1363 __INLINE
char * access_block(size_type k) {
return chunks[GetChunkNumber(k)];}
1364 __INLINE
const char * access_block(size_type k)
const {
return chunks[GetChunkNumber(k)];}
1365 __INLINE
char & access_element(size_type k) {
return access_block(k)[GetElementNumber(k)];}
1366 __INLINE
const char & access_element(size_type k)
const {
return access_block(k)[GetElementNumber(k)];}
1368 __INLINE
char & operator [] (size_type i)
1371 return access_element(i);
1373 __INLINE
const char & operator [] (size_type i)
const
1376 return access_element(i);
1378 __INLINE
char & at(size_type i)
1381 return access_element(i);
1383 __INLINE
const char & at(size_type i)
const
1386 return access_element(i);
1388 void inner_resize(size_type new_size)
1390 size_type oldnchunks2 = (
static_cast<uenum
>(m_size) >> block_bits) + ( (m_size & block_bits_mask) ? 1 : 0);
1391 size_type oldn = (
static_cast<uenum
>(oldnchunks2) >> fwd_alloc_chunk_bits) + ( (oldnchunks2 & fwd_alloc_chunk_bits_mask) ? 1 : 0);
1392 size_type newnchunks2 = (
static_cast<uenum
>(new_size) >> block_bits) + ( (new_size & block_bits_mask)? 1 : 0);
1393 size_type newn = (
static_cast<uenum
>(newnchunks2) >> fwd_alloc_chunk_bits) + ( (newnchunks2 & fwd_alloc_chunk_bits_mask) ? 1 : 0);
1394 for(size_type q = newnchunks2; q < oldnchunks2; q++)
1396 assert(chunks[q] != NULL);
1398 delete [] chunks[q];
1404 chunks.resize(fwd_alloc_chunk_size*newn);
1408 for(size_type q = oldnchunks2; q < newnchunks2; q++)
1410 assert(chunks[q] == NULL);
1411 chunks[q] =
new char[block_size*record_size];
1412 #if defined(DEBUGMEM)
1413 if( chunks[q] == NULL ) {std::cout << __FILE__ <<
":" << __LINE__ <<
"allocation returns NULL\n";}
1415 assert(chunks[q] != NULL);
1416 std::fill(chunks[q],chunks[q]+block_size*record_size,
char());
1422 size_type capacity()
const
1424 size_type nchunks = ((
static_cast<uenum
>(m_size)>>block_bits) + ((m_size & block_bits_mask)? 1 : 0));
1425 return nchunks*block_val*record_size;
1427 size_type size()
const {
return m_size;}
1428 bool empty()
const {
return size() == 0;}
1431 size_type nchunks = ((
static_cast<uenum
>(m_size)>>block_bits) + ((m_size & block_bits_mask)? 1 : 0));
1432 for(size_type q = 0; q < nchunks; q++)
1435 delete [] chunks[q];
1443 record_size = set_record_size;
1448 record_size = other.record_size;
1450 inner_resize(other.size());
1451 size_type nchunks = ((
static_cast<uenum
>(m_size)>>block_bits) + ((m_size & block_bits_mask)? 1 : 0));
1452 for(size_type k = 0; k < nchunks; k++) memcpy(chunks[k],other.chunks[k],block_size*record_size);
1453 m_size = other.size();
1457 if(
this != &other )
1460 record_size = other.record_size;
1461 inner_resize(other.size());
1462 size_type nchunks = ((
static_cast<uenum
>(m_size)>>block_bits) + ((m_size & block_bits_mask)? 1 : 0));
1463 for(size_type k = 0; k < nchunks; k++) memcpy(chunks[k],other.chunks[k],block_size*record_size);
1464 m_size = other.size();
1469 void resize(size_type n)
1477 #define PADDING_SIZE 4096
1478 template<
typename T>
1482 char padding[PADDING_SIZE-
sizeof(T)];
1492 #if defined(_OPENMP)
1495 template<
typename T>
1511 thread_private(
const T & b)
1514 items =
new thread_private_item<T>[omp_get_max_threads()];
1515 for(
int k = 0; k < omp_get_max_threads(); ++k)
1518 thread_private(
const thread_private & b)
1521 items =
new thread_private_item<T>[omp_get_max_threads()];
1522 for(
int k = 0; k < omp_get_max_threads(); ++k)
1523 items[k].item = b.get(k);
1530 thread_private & operator =(thread_private
const & b)
1532 if( omp_in_parallel() )
1534 items[omp_get_thread_num()].item = b.get();
1538 #pragma omp parallel
1539 items[omp_get_thread_num()].item = b.get();
1543 T & operator *() {
return items[omp_get_thread_num()].item;}
1544 const T & operator *()
const {
return items[omp_get_thread_num()].item;}
1559 T & get() {
return items[omp_get_thread_num()].item;}
1560 const T & get()
const {
return items[omp_get_thread_num()].item;}
1561 T & get(
int k) {
return items[k].item;}
1562 const T & get(
int k)
const {
return items[k].item;}
1563 T * operator ->() {
return &items[omp_get_thread_num()].item;}
1564 const T * operator ->()
const {
return &items[omp_get_thread_num()].item;}
1567 template<
typename T>
1589 item->item = b.get();
1594 item->item = b.get();
1597 T & operator *() {
return item->item;}
1598 const T & operator *()
const {
return item->item;}
1613 T & get() {
return item->item;}
1614 const T & get()
const {
return item->item;}
1615 T & get(
int k) {
return item->item;}
1616 const T & get(
int k)
const {
return item->item;}
1617 T * operator ->() {
return &(item->item);}
1618 const T * operator ->()
const {
return &(item->item);}