// (C) Copyright 2008-10 Lukas Gamper // Brigitte Surer // Bela Bauer // // downgraded by O. Parcollet for compilation with icc11 & boost 1.45 // // Use, modification, and distribution are subject to the Boost Software // License, Version 1.0. (See at .) #include #include #include #include #include #include #include #include #include #include namespace boost{ template class generator { public: static std::size_t const buffer_size = 1000; template generator(Generator const & gen, std::size_t size = buffer_size) : buf(make_shared(gen, size)) , cur(buf->cur) , end(buf->end()) {} inline R const operator()() { if (cur == end) buf->fill(); return *cur++; } inline R const preview() { if (cur == end) buf->fill(); return *cur; } generator(generator const & rhs) : buf(new buffer (*rhs.buf)) , cur(buf->cur) , end(buf->end()) {} generator & operator=(generator rhs) { swap(*this, rhs); return *this; } private: class buffer: public std::vector { public: friend class generator; template buffer(Generator const & gen, std::size_t size) : std::vector(size) , engine(make_shared(gen)) , cur(this->end()) , fill_helper(lambda::bind(std::generate, lambda::_1, lambda::_2, ref(*reinterpret_cast(engine.get())))) , clone(lambda::bind(buffer::template type_keeper, lambda::_1, lambda::_2)) {} template buffer(reference_wrapper gen, std::size_t size) : std::vector(size) , cur(this->end()) , fill_helper(lambda::bind(std::generate, lambda::_1, lambda::_2, gen)) {} buffer(buffer const & rhs) : std::vector(rhs) , cur(this->begin() + (rhs.cur - rhs.begin())) , fill_helper(rhs.fill_helper) , clone(rhs.clone) { if (rhs.engine) clone(*this, rhs); } inline void fill() { fill_helper(this->begin(), this->end()); cur = this->begin(); } private: template static void type_keeper(buffer & lhs, buffer const & rhs) { lhs.engine = make_shared(*reinterpret_cast(rhs.engine.get())); lhs.fill_helper = lambda::bind(std::generate, lambda::_1, lambda::_2, ref(*reinterpret_cast(lhs.engine.get()))); } shared_ptr engine; typename std::vector::const_iterator cur; function::iterator, typename std::vector::iterator)> fill_helper; function clone; }; shared_ptr buf; typename buffer::const_iterator & cur; typename buffer::const_iterator end; }; }