Re[6]: std::алгоритмы
От: Кодт Россия  
Дата: 12.10.05 10:36
Оценка: 1 (1)
Здравствуйте, Valus, Вы писали:

V>>в том то и дело, что придется заводить версию с передачей самого контейнера.

V>>а вот так нельзя?

С помощью эпической силы — всё можно.
Единственная засада, которую нам нужно обойти — это инвалидация итераторов контейнера после его изменения. Лечится путём введения прокси.
template<class Cont>
class lazy_iterator
{
  // ленивые данные
  Cont* cont;
  bool begin;
     // для итератора последовательного доступа есть 2 выделенных позиции: начало и конец;
     // для произвольного - можно указать смещение от начала или от конца (0 - начало, +n - от начала, -1 - конец, -n-1 - от конца)

  bool loaded;
  typename Cont::iterator it;

  void force()
  {
    if(loaded) return;
    it = begin ? cont->begin() : cont->end();
    loaded = true;
  }
public:
  lazy_iterator(Cont* c, bool b) : cont(c), begin(b), loaded(false) {}

  // далее, у всех операторов выполняем force
  typename Cont::iterator operator->() const { force(); return it; }
  typename Cont::reference_type operator*() const { force(); return *it; }
  lazy_iterator& operator++() const { force(); return it; }

  bool operator==(const lazy_iterator& rhs) const
  {
    if(!loaded && !rhs.loaded) return begin == rhs.begin;
    force(); rhs.force();
    return it == rhs.it;
  }
};
template<class Cont> lazy_iterator<Cont> lazy_begin(Cont& c) { return lazy_iterator<Cont>(c,true ); }
template<class Cont> lazy_iterator<Cont> lazy_end  (Cont& c) { return lazy_iterator<Cont>(c,false); }


.......
template<class Iter, class Inserter>
void your_function(Iter begin, Iter end, Inserter ins)
{
  // запихиваем через output iterator - Inserter
  for(int i=0; i<123; ++i) *ins++ = i;
  // обрабатываем через forward iterator'ы
  for_each(begin,end, do_something);
}
.......

your_function(lazy_begin(vec), lazy_end(vec), back_inserter(vec));

Это, разумеется, эскиз и большей частью изврат. Но если уж тебе так припёрло...
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.