26 #ifndef SHORE_CONTAINER_INTPACK_HPP__
27 #define SHORE_CONTAINER_INTPACK_HPP__
37 #include <boost/iterator/iterator_facade.hpp>
38 #include <boost/utility/enable_if.hpp>
73 size_t m_bytecapacity;
87 static size_t significant_bits(
int_type n);
91 void reserve_bit(
const size_t new_bitcapacity);
96 static size_t nbyte(
const size_t nbit,
const bool exact=
false);
101 intpack(
const size_t initialsize=0);
113 void resize(
const size_t new_size);
116 void repack(
size_t new_nbit=std::numeric_limits<size_t>::max());
123 void reserve(
const size_t new_capacity);
135 template<
typename Iter>
138 typedef typename std::iterator_traits<Iter>::value_type value_type;
139 const size_t oldsize=m_size;
143 for(Iter i=beg;i!=
end;++i)
145 const value_type v=*i;
155 const_reference
operator[](
const size_t idx)
const;
161 const_reference
front()
const;
167 const_reference
back()
const;
197 const_iterator
begin()
const;
199 const_iterator
end()
const;
204 static const_iterator
iter_at(
const char*
const data,
205 const size_t nbit,
const size_t idx);
226 const size_t nbit,
const char*
const data,
const size_t pos);
233 void move_by(
const ptrdiff_t n);
269 reference(
const size_t nbit,
char*
const data,
const size_t pos);
276 void move_by(
const ptrdiff_t n);
311 :
public boost::iterator_facade<
312 iterator,int_type,boost::random_access_traversal_tag,reference>
316 friend class boost::iterator_core_access;
329 void advance(difference_type n);
331 difference_type distance_to(
const iterator& other)
const;
333 bool equal(
const iterator& other)
const;
345 reference operator[](difference_type n)
const;
350 :
public boost::iterator_facade<
351 const_iterator,int_type,boost::random_access_traversal_tag,const_reference>
355 friend class boost::iterator_core_access;
368 void advance(difference_type n);
393 static const size_t MAX_NBIT=
sizeof(int_type)<<3;
398 virtual void fwd(
const char*& data,
size_t& ofs,
const size_t n)
const=0;
399 virtual void rev(
const char*& data,
size_t& ofs,
const size_t n)
const=0;
400 virtual void inc(
const char*& data,
size_t& ofs)
const=0;
401 virtual void dec(
const char*& data,
size_t& ofs)
const=0;
402 virtual void fwd(
char*& data,
size_t& ofs,
const size_t n)
const=0;
403 virtual void rev(
char*& data,
size_t& ofs,
const size_t n)
const=0;
404 virtual void inc(
char*& data,
size_t& ofs)
const=0;
405 virtual void dec(
char*& data,
size_t& ofs)
const=0;
406 virtual int_type
read(
const char*
const data,
const size_t ofs)
const=0;
407 virtual void write(
char*
const data,
const size_t ofs,int_type v)
const=0;
409 virtual ptrdiff_t distance(
410 const char*
const data1,
const size_t ofs1,
411 const char*
const data2,
const size_t ofs2)
const=0;
417 template<
size_t NBIT>
421 enum { MAXVAL=~((~(int_type(0)))<<NBIT) };
423 virtual void fwd(
const char*& data,
size_t& ofs,
const size_t n)
const
425 const size_t k=(n*NBIT)+ofs;
430 virtual void rev(
const char*& data,
size_t& ofs,
const size_t n)
const
432 const size_t k=n*NBIT;
441 virtual void inc(
const char*& data,
size_t& ofs)
const
448 virtual void dec(
const char*& data,
size_t& ofs)
const
450 ofs+=(MAX_NBIT-NBIT);
452 data-=
sizeof(int_type);
456 virtual void fwd(
char*& data,
size_t& ofs,
const size_t n)
const
458 const size_t k=(n*NBIT)+ofs;
463 virtual void rev(
char*& data,
size_t& ofs,
const size_t n)
const
465 const size_t k=n*NBIT;
474 virtual void inc(
char*& data,
size_t& ofs)
const
481 virtual void dec(
char*& data,
size_t& ofs)
const
483 ofs+=(MAX_NBIT-NBIT);
485 data-=
sizeof(int_type);
489 virtual int_type
read(
const char*
const data,
const size_t ofs)
const
491 const size_t b=NBIT+ofs;
498 ret=(ret>>(MAX_NBIT-NBIT));
506 virtual void write(
char*
const data,
const size_t ofs,int_type v)
const
508 if(v!=(v&MAXVAL))
throw std::runtime_error(
513 const size_t xb=MAX_NBIT-NBIT;
514 const char*
const bo=
reinterpret_cast<const char*
>(&v)+(xb>>3);
519 virtual ptrdiff_t distance(
520 const char*
const data1,
const size_t ofs1,
521 const char*
const data2,
const size_t ofs2)
const
523 const ptrdiff_t dist1=data2-data1;
524 const ptrdiff_t dist2=ptrdiff_t(ofs2)-ptrdiff_t(ofs1);
525 return ((dist1<<3)+dist2)/ptrdiff_t(NBIT);
534 virtual void fwd(
const char*& data,
size_t& ofs,
const size_t n)
const
539 virtual void rev(
const char*& data,
size_t& ofs,
const size_t n)
const
544 virtual void inc(
const char*& data,
size_t& ofs)
const
549 virtual void dec(
const char*& data,
size_t& ofs)
const
554 virtual void fwd(
char*& data,
size_t& ofs,
const size_t n)
const
559 virtual void rev(
char*& data,
size_t& ofs,
const size_t n)
const
564 virtual void inc(
char*& data,
size_t& ofs)
const
569 virtual void dec(
char*& data,
size_t& ofs)
const
574 virtual int_type
read(
const char*
const data,
const size_t ofs)
const
579 virtual void write(
char*
const data,
const size_t ofs,int_type v)
const
581 if(v!=0)
throw std::runtime_error(
"refcore<0> write");
584 virtual ptrdiff_t distance(
585 const char*
const data1,
const size_t ofs1,
586 const char*
const data2,
const size_t ofs2)
const
588 return ptrdiff_t(ofs2)-ptrdiff_t(ofs1);
595 const char*
const data,
const size_t ofs)
const
597 const int_type ret=
static_cast<shore::uint8_t
>(*data);
598 return ((ret>>(7-ofs))&1);
602 inline void refcore<1>::write(
char*
const data,
const size_t ofs,int_type v)
const
604 if(v>1)
throw std::runtime_error(
"refcore<1> write");
606 const shore::uint8_t sh=7-ofs;
607 (*data)&=(~shore::uint8_t(1<<sh));
612 inline ptrdiff_t refcore<1>::distance(
613 const char*
const data1,
const size_t ofs1,
614 const char*
const data2,
const size_t ofs2)
const
616 return ((data2-data1)<<3)+(ptrdiff_t(ofs2)-ptrdiff_t(ofs1));
622 inline refcore<2>::int_type refcore<2>::read(
623 const char*
const data,
const size_t ofs)
const
625 const int_type ret=
static_cast<shore::uint8_t
>(*data);
626 return ((ret>>(6-ofs))&3);
630 inline void refcore<2>::write(
char*
const data,
const size_t ofs,int_type v)
const
632 if(v>3)
throw std::runtime_error(
"refcore<2> write");
634 const shore::uint8_t sh=(6-ofs);
635 (*data)&=(~shore::uint8_t(3<<sh));
640 inline ptrdiff_t refcore<2>::distance(
641 const char*
const data1,
const size_t ofs1,
642 const char*
const data2,
const size_t ofs2)
const
644 return ((data2-data1)<<2)+((ptrdiff_t(ofs2)-ptrdiff_t(ofs1))>>1);
654 virtual void fwd(
const char*& data,
size_t& ofs,
const size_t n)
const
656 const size_t k=(n<<1)+n+ofs;
661 virtual void rev(
const char*& data,
size_t& ofs,
const size_t n)
const
663 const size_t k=(n<<1)+n;
672 virtual void inc(
const char*& data,
size_t& ofs)
const
679 virtual void dec(
const char*& data,
size_t& ofs)
const
687 virtual void fwd(
char*& data,
size_t& ofs,
const size_t n)
const
689 const size_t k=(n<<1)+n+ofs;
694 virtual void rev(
char*& data,
size_t& ofs,
const size_t n)
const
696 const size_t k=(n<<1)+n;
705 virtual void inc(
char*& data,
size_t& ofs)
const
712 virtual void dec(
char*& data,
size_t& ofs)
const
720 virtual int_type
read(
const char*
const data,
const size_t ofs)
const
724 const int_type ret1=
static_cast<shore::uint8_t
>(*data)<<(ofs-5);
725 const int_type ret2=
static_cast<shore::uint8_t
>(*(data+1))>>(13-ofs);
726 return (ret1|ret2)&7;
729 const int_type ret=
static_cast<shore::uint8_t
>(*data);
730 return ((ret>>(5-ofs))&7);
733 virtual void write(
char*
const data,
const size_t ofs,int_type v)
const
737 const shore::uint8_t sh1=(ofs-5);
738 const shore::uint8_t sh2=(13-ofs);
739 (*data)&=(~shore::uint8_t(7>>sh1));
741 (*(data+1))&=(~shore::uint8_t(7<<sh2));
742 (*(data+1))|=(v<<sh2);
746 const shore::uint8_t sh=(5-ofs);
747 (*data)&=(~shore::uint8_t(7<<sh));
752 virtual ptrdiff_t distance(
753 const char*
const data1,
const size_t ofs1,
754 const char*
const data2,
const size_t ofs2)
const
756 const ptrdiff_t dist1=data2-data1;
757 const ptrdiff_t dist2=ptrdiff_t(ofs2)-ptrdiff_t(ofs1);
758 return ((dist1<<3)+dist2)/3;
766 const char*
const data,
const size_t ofs)
const
768 const int_type ret=
static_cast<shore::uint8_t
>(*data);
769 if(ofs>0)
return ret&15;
774 inline void refcore<4>::write(
char*
const data,
const size_t ofs,int_type v)
const
776 if(v>15)
throw std::runtime_error(
"refcore<4> write");
778 const shore::uint8_t cv=v;
779 if(ofs==0) (*data)=((*data)&15)|(cv<<4);
780 else (*data)=(((*data)&(15<<4))|cv);
784 inline ptrdiff_t refcore<4>::distance(
785 const char*
const data1,
const size_t ofs1,
786 const char*
const data2,
const size_t ofs2)
const
788 return ((data2-data1)<<1)+((ptrdiff_t(ofs2)-ptrdiff_t(ofs1))>>2);
796 virtual void fwd(
const char*& data,
size_t& ofs,
const size_t n)
const
801 virtual void rev(
const char*& data,
size_t& ofs,
const size_t n)
const
806 virtual void inc(
const char*& data,
size_t& ofs)
const
811 virtual void dec(
const char*& data,
size_t& ofs)
const
816 virtual void fwd(
char*& data,
size_t& ofs,
const size_t n)
const
821 virtual void rev(
char*& data,
size_t& ofs,
const size_t n)
const
826 virtual void inc(
char*& data,
size_t& ofs)
const
831 virtual void dec(
char*& data,
size_t& ofs)
const
836 virtual int_type
read(
const char*
const data,
const size_t ofs)
const
838 return static_cast<shore::uint8_t
>(*data);
841 virtual void write(
char*
const data,
const size_t ofs,int_type v)
const
843 if(v>255)
throw std::runtime_error(
"refcore<8> write");
847 virtual ptrdiff_t distance(
848 const char*
const data1,
const size_t ofs1,
849 const char*
const data2,
const size_t ofs2)
const
851 return (data2-data1);
860 virtual void fwd(
const char*& data,
size_t& ofs,
const size_t n)
const
865 virtual void rev(
const char*& data,
size_t& ofs,
const size_t n)
const
870 virtual void inc(
const char*& data,
size_t& ofs)
const
875 virtual void dec(
const char*& data,
size_t& ofs)
const
880 virtual void fwd(
char*& data,
size_t& ofs,
const size_t n)
const
885 virtual void rev(
char*& data,
size_t& ofs,
const size_t n)
const
890 virtual void inc(
char*& data,
size_t& ofs)
const
895 virtual void dec(
char*& data,
size_t& ofs)
const
900 virtual int_type
read(
const char*
const data,
const size_t ofs)
const
905 virtual void write(
char*
const data,
const size_t ofs,int_type v)
const
908 const char*
const ptr=
reinterpret_cast<const char*
>(&v);
919 virtual ptrdiff_t distance(
920 const char*
const data1,
const size_t ofs1,
921 const char*
const data2,
const size_t ofs2)
const
923 return (data2-data1)>>3;
942 #endif // SHORE_CONTAINER_INTPACK_HPP__