Topic: Question about fill_n


Author: James Kanze <james-albert.kanze@vx.cit.alcatel.fr>
Date: 1997/03/13
Raw View
Roman Lechtchinsky <wolfro@cs.tu-berlin.de> writes:

|>  James Kanze wrote:
|>  >
|>  > Roman Lechtchinsky <wolfro@cs.tu-berlin.de> writes:
|>  >
|>  > |>  the fill_n algorithm ( 25.2.5 [lib.alg.fill] ) is declared as:
|>  > |>
|>  > |>  template<class OutputIterator, class Size, class T>
|>  > |>  void fill_n( OutputIterator first, Size n, const T& value );
|>  > |>
|>  > |>  and requires that "Size is convertible to an integral type"
|>  > |>  (search_n and generate_n have similar requirements ). This doesn't
|>  > |>  seem to guarantee that n can be incremented or decremented.
|>  >
|>  > So which "integral types" don't support incrementation or
|>  > decrementation.
|>
|>  They all do, of course. Note, however, that Size is merely required to
|>  be *convertible* to an integral type. Thus, a class which provides a
|>  user-defined conversion to an integral type ( e.g. operator int() )
|>  seems to meet this requirement even though it might not support
|>  incrementation and decrementation.

Correct.  I missed this.  And as another poster pointed out, "int const"
is also an integral type:-).

Of course, all this means is that you have to write fill_n cleanly:

    void
    fill_n( OutputIterator first , Size n , const T& value )
    {
     assert( n >= 0 ) ;
     for ( unsigned long cnt( n ) ; cnt > 0 ; cnt -- )
         *first ++ = value ;
    }

I'll admit that in most cases, I'd probaby just use n as a counter as
well.  (This above solution is particularly painful if Size is int, and
int arithmetic is significantly faster than long.)

|>  > (There are exactly 9 integral types: char, signed char,
|>  > unsigned char, short, unsigned short, int, unsigned int, long and
|>  > unsigned long.  All of them support incrementation and decrementation.)
|>
|>  You've forgotten bool and wchar_t, I believe.

Correct.  I was thinking of C.

--
James Kanze      home:     kanze@gabi-soft.fr        +33 (0)1 39 55 85 62
                 office:   kanze@vx.cit.alcatel.fr   +33 (0)1 69 63 14 54
GABI Software, Sarl., 22 rue Jacques-Lemercier, F-78000 Versailles France
     -- Conseils en informatique industrielle --
---
[ 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: marcsh@corel.ca (Marc Sherman)
Date: 1997/03/13
Raw View
In article <rf5vi6wjcq4.fsf@vx.cit.alcatel.fr>, James Kanze
<james-albert.kanze@vx.cit.alcatel.fr> wrote:
>Of course, all this means is that you have to write fill_n cleanly:
>
>    void
>    fill_n( OutputIterator first , Size n , const T& value )
>    {
>        assert( n >= 0 ) ;
>        for ( unsigned long cnt( n ) ; cnt > 0 ; cnt -- )
>            *first ++ = value ;
>    }
>
>I'll admit that in most cases, I'd probaby just use n as a counter as
>well.  (This above solution is particularly painful if Size is int, and
>int arithmetic is significantly faster than long.)

If this were the case in a given implementation, could the library
vendor not provide a partial specialization for Size==int?

- Marc
---
[ 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: Roman Lechtchinsky <wolfro@cs.tu-berlin.de>
Date: 1997/03/11
Raw View
Hi,

the fill_n algorithm ( 25.2.5 [lib.alg.fill] ) is declared as:

template<class OutputIterator, class Size, class T>
void fill_n( OutputIterator first, Size n, const T& value );

and requires that "Size is convertible to an integral type" ( search_n
and generate_n have similar requirements ). This doesn't seem to
guarantee that n can be incremented or decremented. Yet all
implementations of the STL I'm familiar with implement fill_n as:

while( n-->0 ) *first++ = value;

In fact, this seems the only reasonable thing to do but IMO it isn't
conforming, unfortunately. Now, who's wrong - the implementors, the WP
or me?


Bye

Roman
---
[ 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: James Kanze <james-albert.kanze@vx.cit.alcatel.fr>
Date: 1997/03/12
Raw View
Roman Lechtchinsky <wolfro@cs.tu-berlin.de> writes:

|>  the fill_n algorithm ( 25.2.5 [lib.alg.fill] ) is declared as:
|>
|>  template<class OutputIterator, class Size, class T>
|>  void fill_n( OutputIterator first, Size n, const T& value );
|>
|>  and requires that "Size is convertible to an integral type" ( search_n
|>  and generate_n have similar requirements ). This doesn't seem to
|>  guarantee that n can be incremented or decremented.

So which "integral types" don't support incrementation or
decrementation.  (There are exactly 9 integral types: char, signed char,
unsigned char, short, unsigned short, int, unsigned int, long and
unsigned long.  All of them support incrementation and decrementation.)

|>  Yet all
|>  implementations of the STL I'm familiar with implement fill_n as:
|>
|>  while( n-->0 ) *first++ = value;
|>
|>  In fact, this seems the only reasonable thing to do but IMO it isn't
|>  conforming, unfortunately. Now, who's wrong - the implementors, the WP
|>  or me?

You.  Look up the definition of "integral type" in the draft.

--
James Kanze      home:     kanze@gabi-soft.fr        +33 (0)1 39 55 85 62
                 office:   kanze@vx.cit.alcatel.fr   +33 (0)1 69 63 14 54
GABI Software, Sarl., 22 rue Jacques-Lemercier, F-78000 Versailles France
     -- Conseils en informatique industrielle --
---
[ 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: Roman Lechtchinsky <wolfro@cs.tu-berlin.de>
Date: 1997/03/12
Raw View
James Kanze wrote:
>
> Roman Lechtchinsky <wolfro@cs.tu-berlin.de> writes:
>
> |>  the fill_n algorithm ( 25.2.5 [lib.alg.fill] ) is declared as:
> |>
> |>  template<class OutputIterator, class Size, class T>
> |>  void fill_n( OutputIterator first, Size n, const T& value );
> |>
> |>  and requires that "Size is convertible to an integral type" ( search_n
> |>  and generate_n have similar requirements ). This doesn't seem to
> |>  guarantee that n can be incremented or decremented.
>
> So which "integral types" don't support incrementation or
> decrementation.

They all do, of course. Note, however, that Size is merely required to
be *convertible* to an integral type. Thus, a class which provides a
user-defined conversion to an integral type ( e.g. operator int() )
seems to meet this requirement even though it might not support
incrementation and decrementation.

> (There are exactly 9 integral types: char, signed char,
> unsigned char, short, unsigned short, int, unsigned int, long and
> unsigned long.  All of them support incrementation and decrementation.)

You've forgotten bool and wchar_t, I believe.


Bye

Roman
---
[ 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: brad@cfar.umd.edu (Brad Stuart)
Date: 1997/03/12
Raw View
James Kanze (james-albert.kanze@vx.cit.alcatel.fr) wrote:
: Roman Lechtchinsky <wolfro@cs.tu-berlin.de> writes:

: |>  the fill_n algorithm ( 25.2.5 [lib.alg.fill] ) is declared as:
: |>
: |>  template<class OutputIterator, class Size, class T>
: |>  void fill_n( OutputIterator first, Size n, const T& value );
: |>
: |>  and requires that "Size is convertible to an integral type" ( search_n
: |>  and generate_n have similar requirements ). This doesn't seem to
: |>  guarantee that n can be incremented or decremented.

: So which "integral types" don't support incrementation or
: decrementation.  (There are exactly 9 integral types: char, signed char,
: unsigned char, short, unsigned short, int, unsigned int, long and
: unsigned long.  All of them support incrementation and decrementation.)

fill_n isn't necessarily decrementing an "integral type."  It's
decrementing an object of type Size, which may just be some class
having a conversion operator:

class ConstantInt {
public:
 ConstantInt(int c);
 operator int() const;
private:
 const int value;
};

Actually, this is superfluous.  The type "const int" itself doesn't
support inc/decrementation.

But maybe we are also misunderstanding the term "convertible to."

Brad

--
| Brad Stuart      brad@cfar.umd.edu
| Center for Automation Research
| University of Maryland, College Park
---
[ 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                             ]