diff options
author | graehl <graehl@ec762483-ff6d-05da-a07a-a48fb63a330f> | 2010-08-18 21:26:55 +0000 |
---|---|---|
committer | graehl <graehl@ec762483-ff6d-05da-a07a-a48fb63a330f> | 2010-08-18 21:26:55 +0000 |
commit | 8ec14f00d1078f0fa7ab3ba2a01954b1f6ca5260 (patch) | |
tree | 2c065af3a449a50eccb1c30d140bf21a324c850d /utils/value_array.h | |
parent | 0017c952afb4076025098165414d8ca745107f2b (diff) |
ValueArray instead of string for state - same LM decode scores
git-svn-id: https://ws10smt.googlecode.com/svn/trunk@593 ec762483-ff6d-05da-a07a-a48fb63a330f
Diffstat (limited to 'utils/value_array.h')
-rwxr-xr-x | utils/value_array.h | 241 |
1 files changed, 241 insertions, 0 deletions
diff --git a/utils/value_array.h b/utils/value_array.h new file mode 100755 index 00000000..cdf1d697 --- /dev/null +++ b/utils/value_array.h @@ -0,0 +1,241 @@ +#ifndef VALUE_ARRAY_H +#define VALUE_ARRAY_H + +//TODO: option for non-constructed version (type_traits pod?), option for small array optimization (if sz < N, store inline in union, see small_vector.h) + +#include <cstdlib> +#include <algorithm> +#include <new> +#include <boost/range.hpp> +#include <boost/utility/enable_if.hpp> +#include <boost/type_traits.hpp> +#include <cstring> +#ifdef USE_BOOST_SERIALIZE +# include <boost/serialization/split_member.hpp> +# include <boost/serialization/access.hpp> +#endif + +//TODO: use awesome type traits (and/or policy typelist argument) to provide these only when possible? +#define VALUE_ARRAY_ADD 1 +#define VALUE_ARRAY_MUL 1 +#define VALUE_ARRAY_BITWISE 0 +#define VALUE_ARRAY_OSTREAM 1 + +#if VALUE_ARRAY_OSTREAM +# include <iostream> +#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. +{ + typedef ValueArray<T,A> Self; +public: +#if VALUE_ARRAY_OSTREAM + friend inline std::ostream & operator << (std::ostream &o,Self const& s) { + o<<'['; + for (unsigned i=0,e=s.size();i<e;++i) { + if (i) o<<' '; + o<<s[i]; + } + o<<']'; + return o; + } +#endif + static const int SV_MAX=sizeof(T)/sizeof(T*)>1?sizeof(T)/sizeof(T*):1; + //space optimization: SV_MAX T will fit inside what would otherwise be a pointer to heap data. todo in the far future if bored. + 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()) + { + init(s,t); + } + +protected: + inline void init(size_type s, const_reference t = T()) { + sz=s; + array=s ? A::allocate(s) : 0; + for (size_type i = 0; i != sz; ++i) { A::construct(array + i,t); } + } +public: + void resize(size_type s, const_reference t = T()) { + clear(); + init(s,t); + } + + template <class I> + ValueArray(I itr, I end) + : sz(std::distance(itr,end)) + , array(A::allocate(sz)) + { + copy_construct(itr,end,array); + } + + ~ValueArray() { + clear(); + } + +#undef VALUE_ARRAY_OPEQ +#define VALUE_ARRAY_OPEQ(op) template <class T2,class A2> Self & operator op (ValueArray<T2,A2> const& o) { assert(sz==o.sz); for (int i=0,e=sz;i<=e;++i) array[i] op o.array[i]; return *this; } +#if VALUE_ARRAY_ADD + VALUE_ARRAY_OPEQ(+=) + VALUE_ARRAY_OPEQ(-=) +#endif +#if VALUE_ARRAY_MUL + VALUE_ARRAY_OPEQ(*=) + VALUE_ARRAY_OPEQ(/=) +#endif +#if VALUE_ARRAY_BITWISE + VALUE_ARRAY_OPEQ(|=) + VALUE_ARRAY_OPEQ(*=) +#endif +#undef VALUE_ARRAY_OPEQ +#undef VALUE_ARRAY_BINOP +#define VALUE_ARRAY_BINOP(op,opeq) template <class T2,class A2> friend inline Self operator op (Self x,ValueArray<T2,A2> const& y) { x opeq y; return x; } +#if VALUE_ARRAY_ADD + VALUE_ARRAY_BINOP(+,+=) + VALUE_ARRAY_BINOP(-,-=) +#endif +#if VALUE_ARRAY_MUL + VALUE_ARRAY_BINOP(*,*=) + VALUE_ARRAY_BINOP(/,/=) +#endif +#if VALUE_ARRAY_BITWISE + VALUE_ARRAY_BINOP(|,|=) + VALUE_ARRAY_BINOP(*,*=) +#endif + +#undef VALUE_ARRAY_BINOP + void clear() + { + 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) + : A(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() ); +} + +template <class T,class A> +void memcpy(void *out,ValueArray<T,A> const& v) { + std::memcpy(out,v.begin(),v.size()*sizeof(T)); +} + + +#endif |