Topic: Problem with output iterator requirements in WP


Author: "Kevin S. Van Horn" <kevin.s.vanhorn@iname.com>
Date: 1997/07/18
Raw View
I've encountered a troublesome deficiency in the requirements on output
iterators given in the Dec. '96 Working Paper.  The WP does not require
copy assignment to be defined for an output iterator, and in fact it is
not defined for several output iterators in the standard library.  This
can seriously undermine attempts to write generic code.  As an example,
let's look at some code to "htmlize" a sequence of characters, i.e.,
replace the characters '<', '>', '"', and '&' with the character
sequences "&lt;", "&gt;", "&quot;" and "&amp;" respectively.  Attempting
to make this as generic as possible, we might write the following:

  template <class InputIterator, class OutputIterator>
  inline OutputIterator copy_ntcs(InputIterator s, OutputIterator t)
  // "copy null-terminated character sequence"; returns one past the
  // last iterator position written to.
  {
     char c;
     for ( ; c = *s; ++s, ++t)
 *t = c;
     return t;
  }

  template <class OutputIterator>
  OutputIterator htmlize_char(char c, OutputIterator it)
  // Turn a character into the appropriate sequence.  Returns
  // one past the last iterator position written to.
  {
    if (c == '<')
      return copy_ntcs("&lt;", it);
    else if (c == '>')
      return copy_ntcs("&gt;", it);
    else if (c == '&')
      return copy_ntcs("&amp;", it);
    else if (c == '"')
      return copy_ntcs("&quot;", it);
    else {
      *it = c; return ++it;
    }
  }

  template <class InputIterator, class OutputIterator>
  // HTML-encode a null-terminated character sequence.  Returns
  // one past the last iterator position written to.
  inline OutputIterator
  htmlize(InputIterator itin, InputIterator itend,
          OutputIterator itout)
  {
    for ( ; itin != itend; ++itin)
      itout = htmlize_char(*itin, itout);
    return itout;
  }

This is a representative example of a whole class of problems
where you want to write out a sequence of values that is naturally
decomposed into a series of subsequences, with a separate function
call to write out each subsequence.

Unfortunately, it turns out you can't call htmlize() with an output
iterator as the second argument, because output iterators aren't
required to have copy assignment defined, causing problems with this
line:
  itout = htmlize_char(*itin, itout);

It seems unreasonably restrictive to say that a function like htmlize
-- which only uses its second argument for writing -- can't take an
output iterator as a second argument.  And it is quite awkward to work
around this limitation.  One possibility would be to pass in a
reference to an output iterator instead of a simple value:

  template <class InputIterator, class OutputIterator>
  inline void
  htmlize_ref(InputIterator itin, InputIterator itend,
              OutputIterator & itout);

  template <class OutputIterator>
  void htmlize_char(char c, OutputIterator & it);

  template <class InputIterator, class OutputIterator>
  inline void copy_ntcs(InputIterator s, OutputIterator & t);

But besides the disadvantage of adding a level of indirection to all
of the output iterator operations, it is also more awkward to use.
For example, with the original htmlize() you can write

  string s;
  htmlize(it, itend, inserter(s, s.begin()));

but with htmlize_ref you have to write

  string s;
  insert_iterator<string> j(s, s.begin());
  htmlize_ref(it, itend, j);

because the second parameter is a reference parameter.  [Side note:
why isn't s.push_back(c) defined for s a string?  I ought to be able
to use back_inserter() in the above example.]

------------------------------------------------------------------
Kevin S. Van Horn            | kevin.s.vanhorn@iname.com
KSVH Software and Consulting | http://www.xmission.com/~ksvhsoft/
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Christian Millour <chris161@club-internet.fr>
Date: 1997/07/19
Raw View
Kevin S. Van Horn wrote:
>
> I've encountered a troublesome deficiency in the requirements on output
> iterators given in the Dec. '96 Working Paper.  The WP does not require
> copy assignment to be defined for an output iterator, and in fact it is
> not defined for several output iterators in the standard library.

By my reading of the DWP, copy-assignment is required. Also,
SGI stl makes output_iterator a refinement of Assignable
(see http://www.sgi.com/Technology/STL/OutputIterator.html).
I think you are experiencing implementation limitations in
your version of STL.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Matt Austern <austern@isolde.mti.sgi.com>
Date: 1997/07/22
Raw View
Christian Millour <chris161@club-internet.fr> writes:

> Kevin S. Van Horn wrote:
> >
> > I've encountered a troublesome deficiency in the requirements on output
> > iterators given in the Dec. '96 Working Paper.  The WP does not require
> > copy assignment to be defined for an output iterator, and in fact it is
> > not defined for several output iterators in the standard library.
>
> By my reading of the DWP, copy-assignment is required. Also,
> SGI stl makes output_iterator a refinement of Assignable
> (see http://www.sgi.com/Technology/STL/OutputIterator.html).
> I think you are experiencing implementation limitations in
> your version of STL.

Late-breaking news from London: as of three days ago, assignment is
now part of the output iterator requirements.  At the time of Kevin's
post, he was right that it was not part of the requirements.

The SGI STL did put assignment in the output iterator requirements
(largely because of the sorts of problems that Kevin identified), but
that was an extension.  Fortunately, the standardization committee has
now adopted it.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]