/********************************************************************/ /* Copyright (c) 2017 System fugen G.K. and Yuzi Mizuno */ /* All rights reserved. */ /********************************************************************/ #ifndef _MGPvector_HH_ #define _MGPvector_HH_ #if _MSC_VER > 1000 #pragma once #endif /// _MSC_VER > 1000 #include #include #include "mg/MGCL.h" /** @file */ /** @addtogroup BASE * @{ */ ///Defines Vector of newed object pointers. ///MGPvector is a list of std::auto_ptr. The member pointers of newed objects will ///be destructed when MGPList object is destructed. That is, the ownerships of the members //of MGPvector are transfered to MGPvector, and at the copy and assignment of MGPvector, ///all of the ownerships will be transfered to the copied or assigned new MGPvector. template class MGPvector{ public: /// Alias. /// 別名定義 typedef typename std::vector::iterator iterator; typedef typename std::vector::const_iterator const_iterator; typedef typename std::vector::reverse_iterator reverse_iterator; typedef typename std::vector::const_reverse_iterator const_reverse_iterator; typedef typename std::vector::reference reference; typedef typename std::vector::const_reference const_reference; typedef typename std::vector::size_type size_type; ///Member data std::vector m_vector; /// Debug out template MG_DLL_DECLR friend std::ostream& operator<< (std::ostream& out, const MGPvector& vector); //////////// Constructor. ///////// ///void constructor MGPvector(){;} ///default constructor /// Create a vector whose size is n. ///長さlenのベクトルを作成します。 ///すべての要素はNULLで初期化されます。 explicit MGPvector(size_type len) : m_vector(len, 0){;} ///Construct MGPvector of length 1 that contains ptr MGPvector(T* ptr) : m_vector(1, ptr){;} ///copy constructor /// The argument rhs will be cleared, since the ownership /// of all data of rhs should be transfered to this object. ///所有権はすべて、新しいオブジェクトに移るので ///rhsのすべての要素はNULLになります。(sizeは変わりません) MGPvector(const MGPvector& rhs) :m_vector(rhs.m_vector){ MGPvector& rhsp=const_cast&>(rhs); rhsp.m_vector.clear(); } ///Conversion constructor. MGPvector(const std::vector& rhs) :m_vector(rhs.size()){ int n=rhs.size(); for(int i=0; i MGPvector(InputIter first, InputIter last){ insert(end(), first, last); } //////////// destructor //////////// /// Destroy the object and delete all pointers that this object holds. ~MGPvector(); //////////// operator overload //////////// /// Subscript access. const_reference operator[](size_type pos) const{ /// if(pos>=size()) return 0; return m_vector[pos]; } reference operator[](size_type pos){ /// if(pos>=size()) return 0; return m_vector[pos]; } /// assignment operator /// The argument rhs will be empty after assignment, /// and transfer the ownership of all pointers to this object. ///代入演算子 ///所有権はすべて、新しいオブジェクトに移るので ///rhsのすべての要素はNULLになります。(sizeは変わりません) MGPvector& operator=(const MGPvector& rhs); //////////// Member function //////////// /// Assignment that takes a range. /// The intersection of this object and [first, last) must be empty. template void assign(InputIter first, InputIter last){ iterator cur= begin(); for(; first != last && cur != end(); ++first, ++cur){ delete *cur; *cur = *first; } (first == last) ? erase(cur, end()) : insert(end(), first, last); } void assign(size_type pos, T* ptr){ delete m_vector[pos]; m_vector[pos]=ptr; } /// Equivalent to call vector::at(n). const_reference at(size_type n) const{ return m_vector.at(n); } reference at(size_type n){ return m_vector.at(n); } /// Return the reference to the last element in the sequence. /// If the vector is empty, behavior is undefined. const_reference back() const{ return m_vector.back(); } reference back(){ return m_vector.back(); } /// Return const_iterator that points to the first element in the sequence. const_iterator begin() const{ return m_vector.begin(); } /// Return iterator that points to the first element in the sequence. iterator begin(){ return m_vector.begin(); } /// Equivalent to call vector::capacity(). size_type capacity() const{ return m_vector.capacity(); } /// clear Sequence, that is, erase all the elements in the sequence. void clear(){ for(iterator i = begin(); i != end(); ++i) delete *i; m_vector.clear(); } ///Return true (1) if there are no items in the vector, /// false(0) otherwise. bool empty() const{ return m_vector.empty(); } /// Return const_iterator that points one past the last element. const_iterator end() const{ return m_vector.end(); } /// Return iterator that points one past the last element. iterator end(){ return m_vector.end(); } ///erase the element at x. iterator erase(iterator x){ delete *x; return m_vector.erase(x); } ///erase i-th element x. iterator erase(size_type i){ iterator del = m_vector.begin() + i; delete *del; return m_vector.erase(del); } /// erase sequence [first, last). iterator erase(iterator first, iterator last){ iterator cur = first; for(; cur != last; ++cur) delete *cur; return m_vector.erase(first, last); } /// Return the reference to first element in the vector. /// If the vector is empty, behavior is undefined. const_reference front() const{ return m_vector.front(); } reference front(){ return m_vector.front(); } ///ただのポインタを返す。所有権は放棄しないので ///このポインタを解放してはならない。 const_reference get(size_type i) const{ return this->operator[](i); } reference get(size_type i){ return this->operator[](i); } /// Insert ptr into vector at pos. iterator insert(iterator pos, T* ptr){ return m_vector.insert(pos, ptr); } /// Insert the range [first, last) into the vector at pos. template void insert(iterator pos, InputIter first, InputIter last){ for(; first != last; ++first){ pos = insert(pos, *first); ++pos; } } ///Test if i-th element is null. bool is_null(size_type i)const{ return m_vector[i]==0; } ///Returns the size of maximum size. size_type max_size() const{ return m_vector.max_size(); } /// pop last element. void pop_back(){ delete m_vector.back(); m_vector.pop_back(); } /// push element x at the end. void push_back(T* x){ m_vector.push_back(x); } /// push element x at the end. ///All the ownership of the elements in dst are transfered ///to this Pvector. void push_back(MGPvector& dst){ m_vector.insert(m_vector.end(), dst.m_vector.begin(), dst.m_vector.end()); dst.m_vector.clear(); } /// Return const_reverse_iterator that points the end of the sequence. const_reverse_iterator rbegin() const{ return m_vector.rbegin(); } /// Return reverse_iterator that points the end of the sequence. reverse_iterator rbegin(){ return m_vector.rbegin(); } /// Return const_reverse_iterator that points to one before the /// first element in the vector. const_reverse_iterator rend() const{ return m_vector.rend(); } /// Return reverse_iterator that points to one before the /// first element in the vector. reverse_iterator rend(){ return m_vector.rend(); } ///現在の所有権を放棄し、ただのポインタを返す。 ///この処理の後はget(i)==nullとなる。 ///ベクトルの要素自体は削除されません。 T* release(size_type i){ T* ret = m_vector[i]; m_vector[i] = 0; return ret; } ///現在の所有権をすべて放棄する。 ///この処理の後はget(i)==nullとなる。 ///ベクトルの要素自体は削除されない。 void release_all(){ m_vector.assign(size(), static_cast(0)); } ///Remove the T* and return the T*. If i is no valid, /// behavior is undefined. T* removeAt(iterator i){ T* ret = *i; m_vector.erase(i); return ret; } ///Remove the i-th T* in the vector and return the T*. ///If i is not valid, the behavior is undefined. T* removeAt(size_type i){ T* ret = m_vector[i]; iterator del = m_vector.begin() + i; m_vector.erase(del); return ret; } ///reverse the sequence of the elements. void reverse_sequence(){ size_type i,n=size(); size_type nhalf=n/2; for(i=0; i& x){ m_vector.swap(x.m_vector); } }; /////////////////////////////////////////////////////////////////////////////// /// Implementation. /////////////////////////////////////////////////////////////////////////////// template MGPvector::~MGPvector(){ for(iterator i = begin(); i != end(); ++i) delete *i; } template MGPvector& MGPvector::operator=(const MGPvector& rhs){ if(this != &rhs){ clear(); ///もとのデータをクリア m_vector = rhs.m_vector; ///代入する。 MGPvector& rhsp=const_cast&>(rhs); rhsp.m_vector.clear(); ///代入元をクリア } return *this; } ///Resize the vector. ///When size is enlarged, enlarged part will contain null pointer. template void MGPvector::resize(size_type n){ size_type oldn=m_vector.size(); if(oldnn){ for(size_type i=n; i std::ostream& operator<< (std::ostream& out, const MGPvector& vector){ out << "MGPvector::"; int n=vector.size(); out<<"number of entries="<::const_iterator itr; int i=0; for(itr=vector.begin(); itr!=vector.end(); itr++){ out<