diff options
Diffstat (limited to 'decoder')
| -rwxr-xr-x | decoder/value_array.h | 163 | 
1 files changed, 163 insertions, 0 deletions
| diff --git a/decoder/value_array.h b/decoder/value_array.h new file mode 100755 index 00000000..bfdd1155 --- /dev/null +++ b/decoder/value_array.h @@ -0,0 +1,163 @@ +#ifndef VALUE_ARRAY_H +#define VALUE_ARRAY_H + +# include <cstdlib> +# include <algorithm> +# include <new> +# include <boost/range.hpp> +# include <boost/utility/enable_if.hpp> +# include <boost/type_traits.hpp> +#ifdef USE_BOOST_SERIALIZE +# include <boost/serialization/split_member.hpp> +# include <boost/serialization/access.hpp> +#endif + +// valarray like in that size is fixed (so saves space compared to vector), but same interface as vector (less resize/push_back/insert, of course) +template <class T, class A = std::allocator<T> > +class ValueArray : A // private inheritance so stateless allocator adds no size. +{ +public: +  typedef T value_type; +  typedef T& reference; +  typedef T const& const_reference; +  typedef T* iterator; +  typedef T const* const_iterator; +  typedef std::size_t size_type; +  typedef std::ptrdiff_t difference_type; +  typedef T* pointer; + +  size_type size() const { return sz; } +  bool empty() const { return size() == 0; } + +  iterator begin() { return array; } +  iterator end() { return array + size(); } +  const_iterator begin() const { return array; } +  const_iterator end() const { return array + size(); } + +  reference operator[](size_type pos) { return array[pos]; } +  const_reference operator[](size_type pos) const { return array[pos]; } + +  reference at(size_type pos) { return array[pos]; } +  const_reference at(size_type pos) const { return array[pos]; } + +  reference front() { return array[0]; } +  reference back() { return array[sz-1]; } + +  const_reference front() const { return array[0]; } +  const_reference back() const { return array[sz-1]; } + +  ValueArray() : sz(0), array(NULL) {} + +  explicit ValueArray(size_type s, const_reference t = T()) +    : sz(s) +    , array(A::allocate(s)) +  { +    for (size_type i = 0; i != sz; ++i) { A::construct(array + i,t); } +  } + +  template <class I> +  ValueArray(I itr, I end) +    : sz(std::distance(itr,end)) +    , array(A::allocate(sz)) +  { +    copy_construct(itr,end,array); +  } + +  ~ValueArray() +  { +    for (size_type i = sz; i != 0; --i) { +      A::destroy(array + (i - 1)); +    } +    if (array != NULL) A::deallocate(array,sz); +  } + +  void swap(ValueArray& other) +  { +    std::swap(sz,other.sz); +    std::swap(array,other.array); +  } + +  ValueArray(ValueArray const& other) +    : sz(other.sz) +    , array(A::allocate(sz)) +  { +    copy_construct(other.begin(),other.end(),array); +  } + +  ValueArray& operator=(ValueArray const& other) +  { +    ValueArray(other).swap(*this); +    return *this; +  } + +  template <class Range> +  ValueArray( Range const& v +              , typename boost::disable_if< boost::is_integral<Range> >::type* = 0) +    : sz(boost::size(v)) +    , array(A::allocate(sz)) +  { +    copy_construct(boost::begin(v),boost::end(v),array); +  } + +  template <class Range> typename +  boost::disable_if< +    boost::is_integral<Range> +   , ValueArray>::type& operator=(Range const& other) +  { +    ValueArray(other).swap(*this); +    return *this; +  } + +private: +//friend class boost::serialization::access; + +template <class I1, class I2> +void copy_construct(I1 itr, I1 end, I2 into) +{ +  for (; itr != end; ++itr, ++into) A::construct(into,*itr); +} + +template <class Archive> +void save(Archive& ar, unsigned int version) const +{ +  ar << sz; +  for (size_type i = 0; i != sz; ++i) ar << at(i); +} + +template <class Archive> +void load(Archive& ar, unsigned int version) +{ +  size_type s; +  ar >> s; +  ValueArray v(s); +  for (size_type i = 0; i != s; ++i) ar >> v[i]; +  this->swap(v); +} +#ifdef USE_BOOST_SERIALIZE +BOOST_SERIALIZATION_SPLIT_MEMBER() +#endif +size_type sz; +pointer array; +}; + + +template <class T, class A> +bool operator==(ValueArray<T,A> const& v1, ValueArray<T,A> const& v2) +{ +  return (v1.size() == v2.size()) and +    std::equal(v1.begin(),v1.end(),v2.begin()); +} + + +template <class T,class A> +bool operator< (ValueArray<T,A> const& v1, ValueArray<T,A> const& v2) +{ +  return std::lexicographical_compare( v1.begin() +                                       , v1.end() +                                       , v2.begin() +                                       , v2.end() ); +} + + + +#endif | 
