28
Oct
0
C++ – Vector container, Fast light and portable
Here is the source of our BVector for the Brainable framework.
I will not comment this post a lot because I only wrote it to share the source code.
Code
#ifndef BVECTOR_HPP
#define BVECTOR_HPP
#include <new>
#include <cstring>
/**
* @author Berenger
* @version 0.5
* @date 24 novembre 2009
* @file BVector.hpp
* @package Utils
* @brief Basic vecctor based on a memory area
*
* This Vector used a memory area, so you have to use it as an array.
* So it is easy and fast to put data at start/end position.
* But it takes a long time to insert or remove value in the center arrea
*
* @must You must give the buffer size if you know it!
*
* @example BVector<int> vec(100);
* @example for(int i = 0 ; i < 10 ;++i) vec.pushBack(i);
* @example
* @example vec[0] = 99;
* @example vec[2] = 100;
* @example
* @example vec.insert(0u,25);
* @example vec.insert(5u,25);
* @example
* @example for(int i = 0 ; i < 5 ;++i) vec.popBack();
*
* @example for(BVector<int>::iterator iter( vec.begin() ); iter != vec.end() ; ++iter){
* @example (*iter)+=5;
* @example }
*/
template<class T>
class BVector {
protected:
T* buffer; /**< memory area*/
int capacity; /**< memory capacity*/
static const int SizeOfT = sizeof(T); /**< size of the object*/
int startIndex; /**< start index*/
int endIndex; /**< end inde*/
static const int DefaultSize = 150; /**< Default size */
static const float DefaultStart = 0.30; /**< Default start position in %*/
public:
/**
*@brief constructor
*/
BVector(){
this->buffer = reinterpret_cast< T* >( new char[sizeof(T)*DefaultSize] );
this->capacity = DefaultSize;
this->endIndex = this->startIndex = this->capacity * DefaultStart;
}
/**
*@brief constructor
*@param inSize the buffer size
*@param inPointOfStart the point of start [0;1]
*/
BVector(const int inSize, const double inPointOfStart = DefaultStart){
this->buffer = reinterpret_cast< T* >( new char[sizeof(T)*inSize]);
this->capacity = inSize;
if(inPointOfStart <= 1 && inPointOfStart >= 0 ) this->endIndex = this->startIndex = static_cast<int>( this->capacity * inPointOfStart );
else this->endIndex = this->startIndex = static_cast<int>( this->capacity * DefaultStart );
}
/**
*@brief destructor
*/
virtual ~BVector(){
while(this->startIndex != this->endIndex){
(&this->buffer[this->startIndex++])->~T();
}
delete [] reinterpret_cast< char* >(this->buffer);
}
/**
*@brief get the buffer capacity
*@return the buffer capacity
*/
int getCapacity() const{
return this->capacity;
}
/**
*@brief set the buffer capacity
*@param in_capacity to change the capacity
*/
void setCapacity(int in_capacity);
/**
*@brief set a value if possible
*@param inPosition the query position
*@param inValue the new value
*/
void set(const int inPosition , const T& inValue){
if(this->startIndex+inPosition < this->endIndex) this->buffer[this->startIndex+inPosition] = inValue;
}
/**
*@brief get a const reference of a given value
*@param inPosition the query position
*@return the value
*/
T& at(const int inPosition ){
return this->buffer[this->startIndex+inPosition];
}
/**
*@brief get a const reference of a given value
*@param inPosition the query position
*@return the value
*/
const T& at(const int inPosition ) const{
return this->buffer[this->startIndex+inPosition];
}
/**
*@brief get a const reference of a given value
*@param inPosition the query position
*@return the value
*/
T& operator[](const int inPosition ){
return this->buffer[this->startIndex+inPosition];
}
/**
*@brief get a const reference of a given value
*@param inPosition the query position
*@return the value
*/
const T& operator[](const int inPosition ) const{
return this->buffer[this->startIndex+inPosition];
}
/**
*@brief Append a value
*@param inValue the value to append
*/
virtual void append ( const T & inValue ){
new((void*)&this->buffer[this->endIndex++]) T(inValue);
if( this->endIndex == this->capacity ){
setCapacity( static_cast<int>(this->capacity * 1.5));
}
}
/**
*@brief Append a value
*@param other the vector to append
*/
virtual void append ( const BVector<T> & other ){
if( this->capacity - this->endIndex < other.size() ) setCapacity(this->capacity + other.size());
for(int index = other.startIndex ; index < other.endIndex ; ++index ){
new((void*)&this->buffer[++this->endIndex]) T(other.buffer[index]);
}
}
/**
*@brief Get a value
*@param inPosition query position
*@return the data at requiered position, or the last data if inPosition is too big
* You must be sure that there is data in the vector
*/
const T& value( const int inPosition ) const{
return this->buffer[this->startIndex + inPosition];
}
/**
*@brief Get a value
*@param inPosition query position
*@param defaultValue defaulf value in case of bad inPosition
*@return the data at requiered position, or the defaultValue if inPosition is too big or vector is empty
*/
const T& value( const int inPosition , const T& defaultValue) const{
inPosition += this->startIndex;
if( inPosition >= this->endIndex ) return defaultValue;
return this->buffer[ inPosition];
}
/**
*@brief last data
*@return end->data
*/
const T & last() const {
return this->buffer[this->endIndex - 1];
}
/**
*@brief last data
*@return end->data
*/
T & last() {
return this->buffer[this->endIndex - 1];
}
/**
*@brief last data
*@return begin->data
*/
const T & first() const {
return this->buffer[this->startIndex];
}
/**
*@brief delete all, then size = 0
*/
void clear(){
while(this->startIndex != this->endIndex){
(&this->buffer[this->startIndex++])->~T();
}
this->endIndex = this->startIndex = this->capacity * (DefaultStart/100.0);
}
/**
*@brief count the value
*@param inValue the value to test
*@return the value occured number
*/
int size() const{
return this->endIndex - this->startIndex;
}
/**
*@brief count the value
*@param inValue the value to test
*@return the value occured number
*/
int count ( const T & inValue ) const{
int counter = 0;
for(int index = this->startIndex ; index < this->endIndex ; ++index){
if(this->buffer[index] == inValue) ++counter;
}
return counter;
}
/**
*@brief test if the vector contains the value
*@param inValue the value to test
*@return true if inValue is found
*/
bool contains ( const T & inValue ) const{
for(int index = this->startIndex ; index < this->endIndex ; ++index){
if(this->buffer[index] == inValue) return true;
}
return false;
}
/**
*@brief test if the vector is empty
*@return true if vector is empty
*/
bool empty() const{
return this->startIndex == this->endIndex;
}
/**
*@brief test the last value
*@param inValue the value to test
*@return true if vector end with the value
*/
bool endsWith ( const T & inValue ) const{
return !empty() && this->buffer[this->endIndex-1] == inValue;
}
/**
*@brief test the first value
*@param inValue the value to test
*@return true if vector start with the value
*/
bool startsWith( const T & inValue ) const{
return !empty() && this->buffer[this->startIndex] == inValue;
}
/**
*@brief test the last value
*@param inValue the value to test
*@param inFrom the offset
*@return the position of the first found inValue or size if not found
*/
int indexOf( const T & inValue, int inFrom = 0 ) const{
inFrom += this->startIndex;
for(int index = this->startIndex ; index < this->endIndex ; ++index){
if(this->buffer[index] == inValue) return index - this->startIndex;
}
return size();
}
/**
*@brief insert a value at a certain position
*@param inPosition where to insert
*@param inValue the value to put
*/
void insert ( int inPosition, T inValue );
/**
*@brief test the last value
*@param inValue the value to test
*@param inFrom the offset
*@return the position of the last found inValue or size if not found
*/
int lastIndexOf ( const T & inValue, int inFrom = 0 ) const;
/**
*@brief create a subvector
*@param inPosition
*@param in_length
*@return the new vector
*/
BVector<T> subvector( int inPosition, int in_length = 0 ) const;
/**
*@brief pop the last node
*/
void popBack(){
if(this->endIndex!=this->startIndex){
--this->endIndex;
(&this->buffer[this->endIndex])->~T();
}
}
/**
*@brief pop the first node
*/
void popFront(){
if(this->endIndex!=this->startIndex){
(&this->buffer[this->endIndex])->~T();
++this->startIndex;
}
}
/**
*@brief push a new node in back
*@param inValue the new value
*/
void pushBack( const T & inValue ){
append(inValue);
}
/**
*@brief push a new node in front
*@param inValue the new value
*/
void pushFront( const T & inValue ){
if( !this->startIndex ){
setCapacity(this->capacity * 1.5);
}
--this->startIndex;
new((void*)&this->buffer[this->startIndex]) T(inValue);
}
/**
*@brief removeAll value occurence
*@param inValue the value to test
*@return the number of value delete
*/
int removeAll ( const T & inValue );
/**
*@brief remove a value at a position
*@param inPosition the position to delete
*/
void removeAt ( int inPosition );
/**
*@brief remove the first value
*@param inValue the value to delete
*@return true if something has been deleted
*/
bool removeOne ( const T & inValue );
/**
*@brief replace all value
*@param inValue the value to delete
*@return true if something has been deleted
*/
void replaceAll( const T & in_oldValue , const T & in_newValue ){
for(int index = this->startIndex ; index != this->endIndex ; ++index){
if(this->buffer[index] == in_oldValue) this->buffer[index] == in_newValue;
}
}
/**
*@brief replace a value to
*@param inPosition the position to replace
*@param in_newValue the new value
*/
void replace( int inPosition , const T & in_newValue ){
inPosition += this->startIndex;
if(inPosition < this->endIndex ) this->buffer[inPosition] == in_newValue;
}
/**
*@brief swap to value
*@param i the first position
*@param j the second position
*/
void swap ( int i, int j );
/**
*@brief test if two vector are different
*@param other the vector to test
*@return true if different
*/
bool operator!= ( const BVector<T> & other ) const{
return !(*this)== other;
}
/**
*@brief test if two vector are equal
*@param other the vector to test
*@return true if equal
*/
bool operator==( const BVector<T> & other ) const;
/**
*@brief concat two vector
*@param other the vector to add
*@return a new vector
*/
BVector<T> operator+ ( const BVector<T> & other ) const{
BVector<T> vec(*this);
vec.append(other);
return vec;
}
/**
*@brief add a vector
*@param other the vector to add
*@return a current vector
*/
BVector<T> & operator+= ( const BVector<T> & other ){
append(other);
return *this;
}
/**
*@brief add a value
*@param inValue the value to add
*@return a current vector
*/
BVector<T> & operator+= ( const T & inValue ){
append(inValue);
return *this;
}
/**
*@brief add a vector
*@param other the vector to add
*@return a current vector
*/
BVector<T> & operator<< ( const BVector<T> & other ){
append(other);
return *this;
}
/**
*@brief add a value
*@param inValue the value to add
*@return a current vector
*/
BVector<T> & operator<< ( const T & inValue ){
append(inValue);
return *this;
}
/**
*@brief set the vector from another
*@param other the vector to copy
*@return the current vector
*/
BVector<T> & operator= ( const BVector<T> & other ){
clear();
append(other);
return *this;
}
/**
*@class iterator
*@brief vector iterator
*/
class iterator{
protected:
BVector* const vec; /**< the vector to work on*/
int index; /**< the current node*/
/**
*@brief constructor
*/
iterator() : vec(NULL),index(0){}
public:
/**
*@brief destructor
*/
virtual ~iterator(){}
/**
*@brief constructor with node
*@param in_node the node
*/
iterator(BVector* inVec) : vec(inVec), index(inVec->start){}
/**
*@brief constructor with node
*@param in_node the node
*/
iterator(BVector* inVec, const int inIndex) : vec(inVec), index(inIndex){}
/**
*@brief copy constructor
*@param inIter the iterator
*/
iterator(const iterator &inIter) : vec(inIter.vec), index(inIter.index) {}
/**
*@brief copy opperator
*@param inIter the iterator
*@return this
*/
iterator &operator=(const iterator &inIter) {
if(inIter.vec == this->vec){
this->index = inIter.index;
}
return *this;
}
/**
*@brief get data pointed by the operator
*@return data
*/
virtual T& operator*() const { return this->vec->buffer[this->index]; }
/**
*@brief get adresse data pointed by the operator
*@return &data
*/
virtual T* operator->() const { return &this->vec->buffer[this->index]; }
/**
*@brief test equality (if data are equal)
*@return true if equal
*/
bool operator==(const iterator &o) const { return this->vec == o.vec && this->index == o.index; }
/**
*@brief test different (if data are different)
*@return true if different
*/
bool operator!=(const iterator &o) const { return this->vec != o.vec || this->index != o.index; }
/**
*@brief progress in the vector
*@return the current iterator
*/
iterator& operator++() { ++this->index; return *this; }
/**
*@brief reverse progress in the vector
*@return the current iterator
*/
iterator& operator--() { --this->index; return *this; }
/**
*@brief progress in the vector
*@return an iterator before progress
*/
iterator operator++(int) { iterator iter(*this); ++this->index; return iter; }
/**
*@brief reverse progress in the vector
*@return an iterator before progress
*/
iterator operator--(int) { iterator iter(*this); --this->index; return iter; }
/**
*@brief test if it is at the begining of vector
*@return true if at the begining
*/
bool begin(){ return this->vec && this->vec->start == this->index; }
/**
*@brief test if it is at the end of vector
*@return true if at the end
*/
bool end(){ return this->vec && this->vec->end == this->index; }
/**
*@brief test if no data are pointed
*@return true not data are pointed
*/
bool null(){ return !this->vec; }
friend class BVector;
};
friend class iterator;
/**
*@class const iterator
*/
class const_iterator : public iterator{
protected:
/**
*@brief constructor
*/
const_iterator() : iterator(){}
public:
/**
*@brief constructor with node
*@param in_node the node
*/
const_iterator(BVector<T> *inVec) : iterator(inVec) {}
/**
*@brief constructor with node
*@param in_node the node
*/
const_iterator(BVector<T>* inVec, const int inIndex) : iterator(inVec,inIndex) {}
/**
*@brief constructor with iterator
*@param inIter the iterator
*/
const_iterator(const iterator &inIter) : iterator(inIter) {}
/**
*@brief destructor
*/
virtual ~const_iterator(){}
/**
*@brief get data pointed by the operator
*@return data
*/
virtual const T& operator*() const { return iterator::operator*(); }
/**
*@brief get adress data pointed by the operator
*@return &data
*/
virtual const T* operator->() const { return iterator::operator*(); }
};
friend class const_iterator;
/**
*@brief get begin iterator
*@return iterator iter(_begin)
*/
iterator begin(){
iterator iter(this,this->startIndex);
return iter;
}
/**
*@brief get end iterator
*@return const_iterator iter(_begin)
*/
const_iterator constBegin() const{
const_iterator iter(this,this->startIndex);
return iter;
}
/**
*@brief get end iterator
*@return const_iterator iter(this->endIndex)
*/
const_iterator constEnd() const{
const_iterator iter(this,this->endIndex);
return iter;
}
/**
*@brief get end iterator
*@return iterator iter(this->endIndex)
*/
iterator end(){
iterator iter(this,this->endIndex);
return iter;
}
/**
*@brief erase the node pointed by an iterator
*@param inIter iterator
*@return new iterator
*/
iterator erase( iterator inIter );
/**
*@brief erase the node pointed by an iterator
*@param inBegin begining of the deleted area
*@param inEnd ending of the deleted area
*@return new iterator
*/
iterator erase( iterator inBegin, iterator inEnd );
/**
*@brief insert a value after an iterator
*@param in_before where to insert
*@param inValue value to add
*@return new iterator
*/
iterator insert( iterator in_before, const T & inValue );
};
template <typename T>
void BVector<T>::setCapacity(int in_capacity){
const int currentSize = this->endIndex - this->startIndex;
int pointOfStart = (in_capacity * this->startIndex / this->capacity);
if( in_capacity < currentSize){
in_capacity = currentSize;
pointOfStart = 0;
}
if( in_capacity == this->capacity ) return;
T* buffer = reinterpret_cast< T* >( new char[sizeof(T)*in_capacity]);
memcpy(&buffer[pointOfStart],&this->buffer[this->startIndex],sizeof(T)*currentSize);
delete [] reinterpret_cast< char* >(this->buffer);
this->buffer = buffer;
this->startIndex = pointOfStart;
this->endIndex -= this->startIndex + currentSize;
this->capacity = in_capacity;
}
// ------------------------------------------------------------------- //
// ------------------------ vector methods --------------------- //
// ------------------------------------------------------------------- //
template <typename T>
void BVector<T>::insert ( int inPosition, T inValue ){
if( (this->endIndex-this->startIndex) == this->capacity){
setCapacity(static_cast<int>(this->capacity * 1.5));
}
inPosition += this->startIndex;
if(inPosition <= this->endIndex){
if(inPosition - this->startIndex > this->endIndex - inPosition
|| this->startIndex == 0){
for(int index = this->endIndex ; index != inPosition ; --index){
this->buffer[index] = this->buffer[index-1];
}
new((void*)&this->buffer[inPosition]) T(inValue);
++this->endIndex;
}
else{
memcpy(&this->buffer[this->startIndex-1],&this->buffer[this->startIndex],sizeof(T));
new((void*)&this->buffer[inPosition]) T(inValue);
}
}
}
template <typename T>
int BVector<T>::lastIndexOf ( const T & inValue, int inFrom ) const{
inFrom += this->startIndex;
for(int index = this->endIndex - 1 ; index >= inFrom ; --index){
if(this->buffer[index] == inValue) return index;
}
return size();
}
template <typename T>
BVector<T> BVector<T>::subvector( int inPosition, int in_length ) const{
BVector vec(in_length * 2,in_length * 0.2);
inPosition += this->startIndex;
while(in_length--){
new((void*)&vec.buffer[vec.end++]) T(this->buffer[inPosition++]);
}
return vec;
}
template <typename T>
int BVector<T>::removeAll ( const T & inValue ){
int index = this->startIndex;
int counter = 0;
// Do we find a value
while( index != this->endIndex && this->buffer[index] != inValue ) ++index;
// There is at least a value
if(index!=this->endIndex){
// Copying here
int copyIndex = index;
++index;
++counter;
// >>
while( index != this->endIndex ){
memcpy(&this->buffer[copyIndex],&this->buffer[index],sizeof(T));
++copyIndex;
++index;
if(this->buffer[index] != inValue){
(&this->buffer[index])->~T();
++index;
++counter;
}
}
// Delete other
this->endIndex = copyIndex;
}
return counter;
}
template <typename T>
void BVector<T>::removeAt ( int inPosition ){
inPosition += this->startIndex;
if(inPosition < this->endIndex){
(&this->buffer[inPosition])->~T();
if(inPosition - this->startIndex > this->endIndex - inPosition){
++inPosition;
memcpy(&this->buffer[inPosition-1],&this->buffer[inPosition],sizeof(T)*(this->endIndex - inPosition));
--this->endIndex;
}
else{
--inPosition;
while( inPosition != this->startIndex ){
memcpy(&this->buffer[inPosition+1],&this->buffer[inPosition],sizeof(T));
--inPosition;
}
memcpy(&this->buffer[inPosition+1],&this->buffer[inPosition],sizeof(T));
++this->startIndex;
}
}
}
template <typename T>
bool BVector<T>::removeOne ( const T & inValue ){
int index = this->startIndex;
while( index != this->endIndex && this->buffer[index] != inValue ) ++index;
if(index!=this->endIndex){
(&this->buffer[index])->~T();
if(index-this->startIndex > this->endIndex-index){
++index;
memcpy(&this->buffer[index-1],&this->buffer[index],sizeof(T)*(this->endIndex-index));
--this->endIndex;
}
else{
--index;
while( index != this->startIndex ){
memcpy(&this->buffer[index+1],&this->buffer[index],sizeof(T));
--index;
}
memcpy(&this->buffer[index+1],&this->buffer[index],sizeof(T));
++this->startIndex;
}
return true;
}
return false;
}
template <typename T>
void BVector<T>::swap ( int i, int j ){
i += this->startIndex;
j += this->startIndex;
if(i < this->endIndex && j < this->endIndex){
T tmp = this->buffer[i];
this->buffer[i] = this->buffer[j];
this->buffer[j] = tmp;
}
}
template <typename T>
bool BVector<T>::operator==( const BVector<T> & other ) const{
if(this->endIndex-this->startIndex != other.end - other.start ) return false;
for(int index = this->startIndex, otherIndex = other.start ; index != this->endIndex ; ++index, ++otherIndex){
if(this->buffer[index] != this->buffer[otherIndex]) return false;
}
return true;
}
// ------------------------------------------------------------------- //
// ------------------------ iterator methods --------------------- //
// ------------------------------------------------------------------- //
template <typename T>
typename BVector<T>::iterator BVector<T>::erase(typename BVector<T>::iterator inIter ){
if(inIter.vec == this && inIter.index < this->endIndex && inIter.index >= this->startIndex){
removeAt(inIter.index - this->startIndex);
if(inIter.index >= this->endIndex ) --inIter.index;
}
return inIter;
}
template <typename T>
typename BVector<T>::iterator BVector<T>::erase(typename BVector<T>::iterator inBegin,
typename BVector<T>::iterator inEnd ){
// check iterators
if( inBegin.vec != this || inEnd.vec != this ||
inBegin.index< this->startIndex || inEnd.index < this->startIndex ||
inBegin.index>=this->endIndex || inEnd.index>=this->endIndex) return begin();
// if end befor begin, swap
if(inBegin.index > inEnd.index){
const int tmp = inEnd.index;
inEnd.index = inBegin.index;
inBegin.index = tmp;
}
// if beginthis->start longer than endthis->end, we work from the end
if(inBegin.index - this->startIndex > this->endIndex - inEnd.index){
// offset is the position difference
int offset = inEnd.index - inBegin.index;
// destructor for the next deleted elements
while(offset--){
(&this->buffer[inBegin.index + offset])->~T();
}
// use memcpy
offset = inEnd.index - inBegin.index;
memcpy(&this->buffer[inBegin.index],&this->buffer[inEnd.index],sizeof(T)*(offset));
// move end indicator
this->endIndex -= offset;
inEnd.index -= offset;
}
else{
int offset = inEnd.index - inBegin.index;
// destructor for the next deleted elements
while(offset--){
(&this->buffer[inBegin.index + offset])->~T();
}
// copy one by one
while(inEnd.index != inBegin.index){
memcpy(&this->buffer[inBegin.index],&this->buffer[inBegin.index-1],sizeof(T));
++inBegin.index;
}
this->startIndex += inEnd.index - inBegin.index;
}
return inBegin;
}
template <typename T>
typename BVector<T>::iterator BVector<T>::insert(typename BVector<T>::iterator in_before, const T & inValue ){
// check iterator index
if(in_before.vec == this && in_before.index < this->endIndex && in_before.index >= this->startIndex){
in_before.index -= this->startIndex;
// insert with normal form
insert(in_before.index, inValue);
// set index to old index +1
in_before.index += this->startIndex + 1;
}
else in_before.index = this->startIndex;
return in_before;
}
#endif
Stack
#ifndef BSTACK_HPP
#define BSTACK_HPP
#include "BVector.h"
/**
* @author Berenger
* @version 0.5
* @date 19 novembre 2009
* @file BStack.hpp
* @package Utils
* @brief Basic stack based on a vector
*
* This list is a container for fast pop and push operation.
* This container is recommended in cas of big size data storage.
* Otherwise use a Vector instead.
*
* @example BStack<int> ss;
* @example
* @example ss.push(0);
* @example ss.pop();
*/
template<class T>
class BStack : protected BVector<T>{
public:
/**
*@brief Constructor
*/
BStack(int inDefaultSize = BVector<T>::DefaultSize):BVector<T>(inDefaultSize,0) {}
/**
*@brief Destructor
*/
~BStack() {}
/**
*@brief push - add a value
*@param inValue the value to add
*/
void push(const T &inValue){ BVector<T>::pushBack(inValue); }
/**
*@brief pop - pop value
*/
void pop() { BVector<T>::popBack(); }
/**
*@brief top - get a value
*@return the value
*/
T& top() { return BVector<T>::last(); }
/**
*@brief top - get a value
*@return the value
*/
const T & top() const{ return BVector<T>::last(); }
/**
*@brief Get the number of items
*@return Vector - Size
*/
int size() const { return BVector<T>::size(); }
};
#endif
Example
#include "BVector.h"
#include "BStack.h"
#include <iostream>
int main(){
BVector<int> vec(100);
for(int i = 0 ; i < 10 ;++i) vec.pushBack(i);
vec[0] = 99;
vec[2] = 100;
vec.insert(0u,25);
vec.insert(5u,25);
for(BVector<int>::iterator iter( vec.begin() ); iter != vec.end() ; ++iter){
std::cout << *iter << " ";
}
std::cout << '\n';
for(int i = 0 ; i < 5 ;++i) vec.popBack();
for(BVector<int>::iterator iter( vec.begin() ); iter != vec.end() ; ++iter){
std::cout << *iter << " ";
}
std::cout << '\n';
BStack<int> ss;
ss.push(0);
ss.pop();
return 0;
}
Download
Enjoyed reading this post?
Subscribe to the RSS feed and have all new posts delivered straight to you.
Subscribe to the RSS feed and have all new posts delivered straight to you.
