discordia@15: // g++ -D RANDOMBAG_MAIN -std=c++11 RandomBag.cpp discordia@15: discordia@15: discordia@15: #include "RandomBag.hpp" discordia@15: discordia@15: #include discordia@15: #include discordia@15: #include discordia@15: #include discordia@15: #include discordia@15: #include discordia@15: #include discordia@15: #include discordia@15: discordia@15: discordia@15: template discordia@15: RandomBag::RandomBag( void ) : discordia@15: N (0), discordia@15: max(1) { discordia@15: data = new T[1]; discordia@15: } discordia@15: discordia@15: template discordia@15: RandomBag::~RandomBag( void ) { discordia@15: // May leak memory. discordia@15: if ( data ) discordia@15: delete[] data; discordia@15: } discordia@15: discordia@15: template discordia@15: void RandomBag::add( T &item ) { discordia@15: if ( max == N ) discordia@15: resize( 2 * max ); discordia@15: data[N++] = item; discordia@15: } discordia@15: discordia@15: template discordia@15: bool RandomBag::is_empty( void ) { discordia@15: return N == 0; discordia@15: } discordia@15: discordia@15: template discordia@15: size_t RandomBag::size( void ) { discordia@15: return N; discordia@15: } discordia@15: discordia@15: template discordia@15: void RandomBag::resize( size_t new_max ) { discordia@15: T *new_data = new T[new_max]; discordia@15: for ( size_t i = 0; i < N; ++i ) discordia@15: new_data[i] = data[i]; discordia@15: T *old_data = data; discordia@15: data = new_data; discordia@15: delete[] old_data; discordia@15: max = new_max; discordia@15: } discordia@15: discordia@15: template discordia@15: typename RandomBag::iterator RandomBag::begin( void ) { discordia@15: return RandomBag::iterator( data, data, data+N ); discordia@15: } discordia@15: discordia@15: template discordia@15: typename RandomBag::iterator RandomBag::end( void ) { discordia@15: return RandomBag::iterator( data, data+N, data+N ); discordia@15: } discordia@15: discordia@15: discordia@15: //////////////////////////////////////////////////////////////////////////////// discordia@15: discordia@15: template discordia@15: RandomBag::iterator::iterator( T *b, T *f, T *e ) : discordia@15: begin (b), discordia@15: first (f), discordia@15: end (e), discordia@15: curr (0) { discordia@15: size_t size = e - f; discordia@15: for ( size_t i = 0; i < size; ++i ) { discordia@15: order.push_back( (first - begin) + i ); discordia@15: } discordia@15: discordia@15: unsigned seed = std::chrono::system_clock::now().time_since_epoch().count(); discordia@15: shuffle (order.begin(), order.end(), std::default_random_engine(seed)); discordia@15: discordia@15: order.push_back( end - begin ); discordia@15: } discordia@15: discordia@15: template discordia@15: typename RandomBag::iterator & RandomBag::iterator::operator++() { discordia@15: if ( this->curr < this->end - this->first ) { discordia@15: this->curr += 1; discordia@15: } discordia@15: return *this; discordia@15: } discordia@15: discordia@15: template discordia@15: typename RandomBag::iterator RandomBag::iterator::operator++( int ) { discordia@15: auto t = RandomBag::iterator( *this ); discordia@15: if ( this->curr < this->end - this->first ) { discordia@15: this->curr += 1; discordia@15: } discordia@15: return t; discordia@15: } discordia@15: discordia@15: template discordia@15: T RandomBag::iterator::operator*() { discordia@15: return *(this->begin + order[curr]); discordia@15: } discordia@15: discordia@15: template discordia@15: bool RandomBag::iterator::operator!=( typename RandomBag::iterator other ) { discordia@15: return (this->begin + this->order[this->curr]) != (other.begin + other.order[other.curr]); discordia@15: } discordia@15: discordia@15: discordia@15: //////////////////////////////////////////////////////////////////////////////// discordia@15: discordia@15: #ifdef RANDOMBAG_MAIN discordia@15: discordia@15: #include discordia@15: discordia@15: int main ( int argc, char **argv ) { discordia@15: discordia@15: RandomBag random_bag; discordia@15: discordia@15: long i; discordia@15: while ( ! std::cin.eof() ) { discordia@15: std::cin >> i; discordia@15: if ( std::cin.good() ) discordia@15: random_bag.add(i); discordia@15: } discordia@15: discordia@15: std::cout << "RandomBag has " << random_bag.size() << " entries." << std::endl; discordia@15: discordia@15: for ( auto iter = random_bag.begin(); iter != random_bag.end(); ++iter ) { discordia@15: std::cout << *iter << std::endl; discordia@15: } discordia@15: discordia@15: discordia@15: } discordia@15: discordia@15: #endif