/** * @file vecque.h * @brief 内部でポインタのvectorで管理するdeque風vector. * @author tenk* * @note * - ポインタのvectorとして実装し、個々の要素を1つ1つアロケート. * - なので、要素間のアドレスは連続しない. * - resize等で内部のvectorでメモリー再確保がおきると、 * vecqueのイテレータは無効になる. * が、要素のメモリ自体はそのままなので、要素へのポインタは変動しない. * - vectorで実装してるので、挿入/削除系を多様する用途には向かない. * (dequeの代用にはあまりならない) * が移動するのはポインタなので、実体が大きい場合は、量を扱える、とも. * - reserveできるのは、ポインタのvectorの部分のみ. * - 現状、実装に気合が入っていないので、要素のallocate/deallocateは * 使いまわし等せず、そのつどダイレクトに行う. * ※ 必要ならばアロケータ側で工夫ということに. * - Public Domain Software */ #ifndef VECQUE_H_INCLUDED #define VECQUE_H_INCLUDED #include <cstddef> #include <iterator> #include <algorithm> #include <functional> #include <new> #include <memory> #include <vector> #ifndef assert #include <cassert> #endif #ifndef UNUSE_THROW #include <stdexcept> #endif #if defined _MSC_VER #pragma warning(push) #pragma warning(disable: 4100) #endif #if defined __WATCOMC__ || defined __DMC__ #define VECQUE_NO_MEMBER_TEMPLATES // メンバーテンプレート未サポートなら定義. #endif // ============================================================================ namespace vecque_detail { template<typename T, class A, class V > class vecque_iterator : public std::iterator< std::random_access_iterator_tag, T > { typedef typename V::iterator raw_iterator; typedef typename V::const_iterator c_raw_iterator; public: vecque_iterator(raw_iterator r=raw_iterator()) : ptr_(r) {} vecque_iterator(const vecque_iterator& r) : ptr_(r.ptr_) {} // ~vecque_iterator(){} T& operator*() { return **ptr_; } const T& operator*() const { return **ptr_; } T* operator->() { return *ptr_; } const T* operator->() const { return *ptr_; } vecque_iterator& operator=(const vecque_iterator& r) { ptr_ = r.ptr_; return *this; } vecque_iterator& operator+=(std::ptrdiff_t n) { ptr_ += n; return *this; } vecque_iterator& operator-=(std::ptrdiff_t n) { ptr_ -= n; return *this; } vecque_iterator& operator++() { ++ptr_; return *this; } vecque_iterator& operator--() { --ptr_; return *this; } vecque_iterator operator++(int) { vecque_iterator p(ptr_); ++ptr_; return p; } vecque_iterator operator--(int) { vecque_iterator p(ptr_); --ptr_; return p; } friend ptrdiff_t operator-(vecque_iterator l, vecque_iterator r) { return l.ptr_ - r.ptr_; } bool operator!=(const vecque_iterator& r) const { return ptr_ != r.ptr_; } bool operator==(const vecque_iterator& r) const { return ptr_ == r.ptr_; } bool operator< (const vecque_iterator& r) const { return ptr_ < r.ptr_; } bool operator<=(const vecque_iterator& r) const { return ptr_ <= r.ptr_; } bool operator> (const vecque_iterator& r) const { return ptr_ > r.ptr_; } bool operator>=(const vecque_iterator& r) const { return ptr_ >= r.ptr_; } raw_iterator get_raw_ptr() { return ptr_; } c_raw_iterator get_raw_ptr() const { return ptr_; } private: raw_iterator ptr_; }; template<typename T, class A, class V > inline vecque_iterator<T,A,V> operator+(const vecque_iterator<T,A,V>& l, std::ptrdiff_t n) { return vecque_iterator<T,A,V>(l) += n; } template<typename T, class A, class V > inline vecque_iterator<T,A,V> operator-(const vecque_iterator<T,A,V>& l, std::ptrdiff_t n) { return vecque_iterator<T,A,V>(l) -= n; } template<typename T, class A, class V > inline vecque_iterator<T,A,V> operator+(std::ptrdiff_t n, const vecque_iterator<T,A,V>& r) { return vecque_iterator<T,A,V>(r) += n; } struct vecque_sort_cmp_ptr_less { template<typename ITE> bool operator()(ITE l, ITE r) const { return *l < *r; } }; } // ============================================================================ template<typename T, class A=std::allocator<T>, class V=std::vector<T*> > class vecque : private A { public: typedef T value_type; typedef A allocator_type; typedef typename A::size_type size_type; typedef typename A::difference_type difference_type; typedef typename A::reference reference; typedef typename A::const_reference const_reference; typedef typename A::pointer pointer; typedef typename A::const_pointer const_pointer; typedef vecque_detail::vecque_iterator<T,A,V> iterator; typedef vecque_detail::vecque_iterator<const T,A,V> const_iterator; typedef std::reverse_iterator<iterator> reverse_iterator; typedef std::reverse_iterator<const_iterator> const_reverse_iterator; vecque() { assert((T*)0 == (typename V::value_type)0); } ~vecque() { clear(); } vecque(const vecque& r); explicit vecque(size_type sz); vecque(size_type sz, const T& t); vecque& operator=(const vecque& x); void assign(size_type n, const T &t); size_type size() const { return vec_.size();} size_type max_size() const { return vec_.max_size();} size_type capacity() const { return vec_.capacity();} bool empty() const { return vec_.empty();} iterator begin() { return iterator(vec_.begin());} const_iterator begin() const { return const_iterator(vec_.begin());} const_iterator cbegin() const { return const_iterator(vec_.begin());} iterator end() { return iterator(vec_.end());} const_iterator end() const { return const_iterator(vec_.end());} const_iterator cend() const { return const_iterator(vec_.end());} reverse_iterator rbegin() { return reverse_iterator( end() );} const_reverse_iterator rbegin() const { return const_reverse_iterator( end() );} const_reverse_iterator crbegin()const { return const_reverse_iterator( end() );} reverse_iterator rend() { return reverse_iterator( begin() ); } const_reverse_iterator rend() const { return const_reverse_iterator( begin() );} const_reverse_iterator crend() const { return const_reverse_iterator( begin() );} reference front() { return *vec_.front(); } const_reference front() const { return *vec_.front(); } reference back() { return *vec_.back(); } const_reference back() const { return *vec_.back(); } reference operator[](size_type n) { assert(n < vec_.size()); return *vec_[n]; } const_reference operator[](size_type n) const { assert(n < vec_.size()); return *vec_[n]; } reference at(size_type n) { return *vec_.at(n); } const_reference at(size_type n) const { return *vec_.at(n); } void clear(); void resize( size_type sz); void reserve(size_type sz) { vec_.reserve(sz); } void push_back(const T& t); void pop_back(); void push_front(const T& t); void pop_front(); iterator erase(iterator pos); iterator erase(iterator first, iterator last); iterator insert(iterator pos, const T& t); iterator insert(iterator pos, size_type n, const T& t); bool operator==(const vecque& r) const; bool operator!=(const vecque& r) const { return !(*this == r); } bool operator< (const vecque& r) const; bool operator>=(const vecque& r) const { return !(*this < r); } bool operator> (const vecque& r) const { return r < *this ; } bool operator<=(const vecque& r) const { return ! (r < *this); } void swap(vecque& r) { vec_.swap(r.vec_); } A& get_allocator() { return *(A*)this; } void sort(); #ifndef VECQUE_NO_MEMBER_TEMPLATES // メンバーテンプレートサポートの場合. template<typename InpIte> vecque(InpIte bgn, InpIte end); template<typename InpIte> void assign(InpIte bgn, InpIte end); template <typename InpIte> iterator insert(iterator pos, InpIte a, InpIte b); //template<class Comp> void sort(Comp comp); #else // メンバーテンプレート未サポートの場合. vecque(iterator bgn, iterator end); void assign(iterator bgn, iterator end); iterator insert(iterator pos, iterator a, iterator b); #endif private: T* alloc1(const T& t); void dealloc1(const T* t); typedef typename V::iterator v_iterator; typedef typename V::const_iterator v_c_iterator; v_iterator ite_to_v_ite(iterator i) { return i.get_raw_ptr(); } private: V vec_; }; // ---------------------------------------------------------------------------- template<typename T, class A, class V > inline T* vecque<T,A,V>::alloc1(const T& t) { T* a = A::allocate(1); if (a) A::construct(a, t); #if 0 //def UNUSE_THROW else notEnoughMemory(); #endif return a; } template<typename T, class A, class V > inline void vecque<T,A,V>::dealloc1(const T* t) { if (t) { A::destroy((T*)t); A::deallocate((T*)t, 1); } } // ---------------------------------------------------------------------------- template<typename T, class A, class V > vecque<T,A,V>::vecque(typename vecque<T,A,V>::size_type sz) : vec_(sz) { for (size_type i = 0; i < sz; ++i) vec_[i] = alloc1(T()); } template<typename T, class A, class V > vecque<T,A,V>::vecque(typename vecque<T,A,V>::size_type sz, const T& t) : vec_(sz) { for (size_type i = 0; i < sz; ++i) vec_[i] = alloc1(t); } #ifndef VECQUE_NO_MEMBER_TEMPLATES // メンバーテンプレートサポートの場合. template<typename T, class A, class V > template<typename InpIte> vecque<T,A,V>::vecque(InpIte bgn, InpIte end) #else // 未サポートの場合. template<typename T, class A, class V > vecque<T,A,V>::vecque(typename vecque<T,A,V>::iterator bgn, typename vecque<T,A,V>::iterator end) #endif { size_type sz = std::distance(bgn, end); vec_.resize(sz); for (size_type i = 0; i < sz; ++i) { vec_[i] = alloc1(*bgn); ++bgn; } } template<typename T, class A, class V > vecque<T,A,V>::vecque(const vecque<T,A,V>& r) : vec_(r.size()) { size_type sz = r.size(); for (size_type i = 0; i < sz; ++i) { vec_[i] = alloc1(r[i]); } } // ---------------------------------------------------------------------------- template<typename T, class A, class V > vecque<T,A,V>& vecque<T,A,V>::operator=(const vecque<T,A,V>& r) { clear(); size_type sz = r.size(); resize(sz); for (size_type i = 0; i < sz; ++i) vec_[i] = alloc1( r[i] ); return *this; } template<typename T, class A, class V > void vecque<T,A,V>::assign(typename vecque<T,A,V>::size_type sz, const T& t) { clear(); resize(sz); for (size_type i = 0; i < sz; ++i) vec_[i] = alloc1(t); } #ifndef VECQUE_NO_MEMBER_TEMPLATES // メンバーテンプレートサポートの場合. template<typename T, class A, class V > template<typename InpIte> void vecque<T,A,V>::assign(InpIte bgn, InpIte end) #else // 未サポートの場合. template<typename T, class A, class V > void vecque<T,A,V>::assign(typename vecque<T,A,V>::iterator bgn, typename vecque<T,A,V>::iterator end) #endif { clear(); size_type sz = std::distance(bgn, end); resize(sz); for (size_type i = 0; i < sz; ++i) { vec_[i] = alloc1(*bgn); ++bgn; } } // ---------------------------------------------------------------------------- template<typename T, class A, class V > void vecque<T,A,V>::clear() { size_type sz = vec_.size(); for (size_type i = 0; i < sz; ++i) dealloc1(vec_[i]); vec_.clear(); } template<typename T, class A, class V > void vecque<T,A,V>::resize( typename vecque<T,A,V>::size_type sz ) { size_type size = vec_.size(); if (sz < size) { for (size_type i = sz; i < size; ++i) dealloc1(vec_[i]); vec_.resize(sz); } else if (sz > size) { vec_.resize(sz); for (size_type i = size; i < sz; ++i) vec_[i] = alloc1(T()); } } template<typename T, class A, class V > void vecque<T,A,V>::push_back( const T& t ) { T* a = alloc1(t); vec_.push_back( a ); } template<typename T, class A, class V > void vecque<T,A,V>::pop_back() { if (!vec_.empty()) { T* a = vec_.back(); dealloc1(a); vec_.pop_back(); } } template<typename T, class A, class V > void vecque<T,A,V>::push_front( const T& t ) { vec_.insert( vec_.begin() , NULL ); vec_[0] = alloc1(t); } template<typename T, class A, class V > void vecque<T,A,V>::pop_front() { if (!vec_.empty()) { T* t = vec_.front(); dealloc1(t); vec_.erase( vec_.begin() ); } } template<typename T, class A, class V > bool vecque<T,A,V>::operator==(const vecque<T,A,V>& rhs) const { size_type lsz = vec_.size(); size_type rsz = rhs.vec_.size(); if (lsz != rsz) return false; const T** l = (const T**)&vec_[0]; const T** le = l + lsz; const T** r = (const T**)&rhs.vec_[0]; //const T** re = (const T**)&*rhs.vec_.end(); while (l != le) { if (**l != **r) return 0; ++l; ++r; } return 1; } template<typename T, class A, class V > bool vecque<T,A,V>::operator< (const vecque<T,A,V>& rhs) const { v_c_iterator l = vec_.begin(); v_c_iterator le = vec_.end(); v_c_iterator r = rhs.vec_.begin(); v_c_iterator re = rhs.vec_.end(); while (l != le) { if (r == re) return 0; if (**l < **r) return 1; if (**r < **l) return 0; ++l; ++r; } return (r != re); } // ---------------------------------------------------------------------------- template<typename T, class A, class V > typename vecque<T,A,V>::iterator vecque<T,A,V>::erase(typename vecque<T,A,V>::iterator pos) { dealloc1( *pos.get_raw_ptr() ); vec_.erase( ite_to_v_ite( pos ) ); return pos; } template<typename T, class A, class V > typename vecque<T,A,V>::iterator vecque<T,A,V>::erase( typename vecque<T,A,V>::iterator first, typename vecque<T,A,V>::iterator last) { // assert(first < last && begin() <= first && last <= end()); for (iterator it = first; it != last; ++it) dealloc1(*it.get_raw_ptr()); vec_.erase( ite_to_v_ite(first), ite_to_v_ite(last) ); return first; } // ---------------------------------------------------------------------------- template<typename T, class A, class V > typename vecque<T,A,V>::iterator vecque<T,A,V>::insert(typename vecque<T,A,V>::iterator pos, const T& t) { return insert(pos, 1U, t); } template<typename T, class A, class V > inline typename vecque<T,A,V>::iterator vecque<T,A,V>::insert( typename vecque<T,A,V>::iterator pos, typename vecque<T,A,V>::size_type n, const T& t) { if (n == 0) return pos; v_iterator p = pos.get_raw_ptr(); size_type idx = p - vec_.begin(); vec_.insert(p, n, (T*)NULL); p = vec_.begin() + idx; do { *p = alloc1(t); ++p; } while (--n); return iterator(p); } #ifndef VECQUE_NO_MEMBER_TEMPLATES // メンバーテンプレートサポートの場合. template<typename T, class A, class V > template <typename InpIte> typename vecque<T,A,V>::iterator vecque<T,A,V>::insert(typename vecque<T,A,V>::iterator pos, InpIte first, InpIte last) #else // 未サポートの場合. template<typename T, class A, class V > typename vecque<T,A,V>::iterator vecque<T,A,V>::insert(typename vecque<T,A,V>::iterator pos , typename vecque<T,A,V>::iterator first , typename vecque<T,A,V>::iterator last) #endif { size_type n = std::distance(first, last); if (n == 0) return pos; v_iterator p = pos.get_raw_ptr(); size_type idx = p - vec_.begin(); vec_.insert(p, n, (T*)NULL); p = vec_.begin(); p += idx; v_iterator e = p; e += n; do { *p = alloc1(*first); ++p; ++first; } while (p != e); return iterator(p); } template<typename T, class A, class V > void vecque<T,A,V>::sort() { std::stable_sort(vec_.begin(), vec_.end(), vecque_detail::vecque_sort_cmp_ptr_less()); } /* #ifndef VECQUE_NO_MEMBER_TEMPLATES // メンバーテンプレートサポートの場合. template<typename T, class A, class V > template<class Comp> void vecque<T,A,V>::sort(Comp comp) { std::stable_sort(begin(), end(), comp); } #endif */ #endif // VECQUE_H_INCLUDED