API foo(), , , curr_output_iter != output_end, (. ), distance() .
" ", "" , , . OutputIterator SafeOutputIterator - , , ++. "" "" : , 2- , .
template <typename Tag>
struct helper {
static bool value = true;
};
template <>
struct helper<output_iterator_tag> {
static bool value = false;
};
template <typename It>
struct is_bounded {
static bool value = helper<typename iterator_traits<It>::iterator_category>::value;
};
template<typename It, bool BOUNDED = is_bounded<It>::value>
class safe_output_iterator {
typedef typename iterator_traits<It>::value_type value_type;
public:
explicit safe_output_iterator(It iter, size_t limit = 0) : iter_(iter), limit_(limit) {}
safe_output_iterator& operator++() {
++iter_;
return *this;
}
safe_output_iterator operator++(int) {
safe_output_iterator temp(*this);
++iter_;
return temp;
}
safe_output_iterator& operator*() {
return *this;
}
safe_output_iterator& operator=() {
--limit_;
return *_iter;
}
bool operator==(safe_output_iterator const& x) {
return BOUNDED && limit_ == x.limit_;
}
bool operator!=(safe_output_iterator const& x) {
return !(*this == x);
}
private:
It iter_;
size_t limit_;
};
template <typename It>
safe_output_iterator<It> soi_begin(It it, size_t limit = 0) {
return safe_output_iterator<It>(it, limit);
}
template <typename It>
safe_output_iterator<It> soi_end(It it, size_t limit = 0) {
return safe_output_iterator<It>(it, limit);
}
template <typename C>
safe_output_iterator<It> soi_begin_cont(C cont) {
return safe_output_iterator<typename C::iterator>(cont.begin(), cont.size());
}
template <typename C>
safe_output_iterator<It> soi_end_cont(C cont) {
return safe_output_iterator<typename C::iterator>(cont.end());
}
, :
vector<int> u(10, 42), v(ENOUGH_SPACE), w, x(ENOUGH_SPACE);
// Explicit iterator pair; bounded
foo(u.begin(), u.end(), soi_begin(v.begin(), ENOUGH_SPACE), soi_end(v));
// Explicit iterator pair; unbounded (2nd iterator ignored, but we need the type)
foo(u.begin(), u.end(), soi_begin(w.back_inserter()), soi_end(w.back_inserter()));
// Use whole container
foo(u.begin(), u.end(), soi_begin_cont(x), soi_end_cont(x));
foo() curr_output_iter != output_end *curr_output_iter, , , safe_output_iterator::operator=(). , , safe_output_iterator (-, , STL). soi_begin_cont() soi_end_cont() .
, STL - , , , .