Wording for range-based for-loop (revision 4)

Author: Thorsten Ottosen
Contact: nesotto@cs.aau.dk
Advisor:Lawrence Crowl, Douglas Gregor and Jens Maurer
Organizations:Department of Computer Science, Aalborg University
Date: 2008-09-18
Number:WG21/N2778 and J16/08-0288
Working Group:Core

Abstract

This paper provides wording for the new range-based for-loop previously described in n1868, n1961, n2049, n2196 , n2243 and n2394.

Table of Contents

Introduction

This document provides wording for a concept-based implementation of the range-based for loop. The proposal is implemented in the latest version of Douglas Gregors Concept GCC.

Each numbered section below describes a new section for the standard or modifications to an existing section. Comments are written in bold up front and are not part of the wording.

The author would like to thank Lawrence Crowl, Steve Adamczyk and Douglas Gregor for their help with the first revisions. Special thanks goes to Jens Maurer for his help with this revision. Any mistake is the responsibility of the author.

Missing parts

The layout of concept headers is not yet finalized. This will only affect the library wording in minor ways and so the wording is included with any reference to the exact section in the standard.

Wording

3.3.2 Local scope

Modify paragraph 4 as indicated:

Names declared in the for-init-statement, the for-range-declaration, and in the condition of if, while, for, and switch statements are local to the if, while, for, or switch statement (including the controlled statement), and shall not be redeclared in a subsequent condition of that statement nor in the outermost block (or, for the if statement, any of the outermost blocks) of the controlled statement; see 6.4 stmt.select.

6.5 Iteration statements

Modify paragraph 1 as indicated:

iteration-statement:
        while ( condition ) statement
        do statement while ( expression ) ;
        for ( for-init-statement conditionopt ; expressionopt ) statement
        for ( for-range-declaration : expression ) statement

for-init-statement:
        expression-statement
        simple-declaration

for-range-declaration:
        type-specifier-seq attribute-specifieropt declarator

Editorial note: if the attribute paper is not passed, remove the attribute-specifier above.

6.5.4 The range-based for statement

Add the following new section:

1 The range-based for statement

for ( for-range-declaration : expression ) statement

is equivalent to

{
     auto && __range = ( expression );

     for ( auto __begin = std::Range<_RangeT>::begin(__range),
                  __end = std::Range<_RangeT>::end(__range);
          __begin != __end;
          ++__begin )
     {
         for-range-declaration = *__begin;
         statement
     }
}

where __range, __begin and __end are variables defined for exposition only, and _RangeT is the type of the expression.

[Example:

int array[5] =  { 1,2,3,4,5 };
for ( int& x : array )
  x *= 2;

-- end example]

2 If the header <iterator_concepts> (24.1) is not included prior to a use of the range-based for statement, the program is ill-formed.

7.1.6.4 auto specifier

Modify paragraph 4 as indicated:

4 The auto type-specifier can also be used in declaring an object in the condition of a selection statement (6.4) or an iteration statement (6.5), in the type-specifier-seq in a new-type-id (5.3.4), in a for-range-declaration, and in declaring a static data member with a constant-initializer that appears within the member-specification of a class definition (9.4.2).

24.1 Iterator concepts [iterator.concepts]

Add the following to the synopsis for header ``<iterator_concepts>``:

concept Range< typename T > see below;

template< class T, size_t N >
concept_map Range< T[N] > see below;

Add the following new section to [iterator.concepts]:

24.1.6 Ranges [iterator.concepts.range]

1 A type T satisfies the requirements of a range if it meets the syntactic and semantic requirements of the Range concept.

concept Range< typename T > {
    InputIterator iterator;
    iterator begin( T& );
    iterator end( T& );
}

2 Note: Any object of a type conforming to the Range concept can be used with the range-based for statement (6.5.4).

3 Requires: For an object t of a type T conforming to the Range concept, [Range<T>::begin(t),Range<T>::end(t)) shall designate a valid range (24.1.7).

template< class T, size_t N >
concept_map Range< T[N] >
{
    typedef T* iterator;
    iterator begin( T(&a)[N] ) { return a; }
    iterator end( T(&a)[N] )   { return a + N; }
};

4 Note: Adapts an array to the Range concept.

18.8 Header <initializer_list>

Add the following to the synopsis:

template<typename T>
concept_map Range< initializer_list<T> > see below;

template<typename T>
concept_map Range< const initializer_list<T> > see below;

Add the following new section that describes <initializer_list>:

18.8.1 Initializer list concept maps

template<typename T>
concept_map Range< initializer_list<T> >
{
    typedef const T* iterator;

    iterator begin( initializer_list<T> r ) { return r.begin(); }
    iterator end( initializer_list<T> r )   { return r.end(); }
}

template<typename T>
concept_map Range< const initializer_list<T> >
{
    typedef const T* iterator;

    iterator begin( initializer_list<T> r ) { return r.begin(); }
    iterator end( initializer_list<T> r )   { return r.end(); }
}

1 Note: Adapts initializer lists to the Range concept.

20.2 Header <utility> synopsis

Add the following to the synopsis:

template<InputIterator Iter>
concept_map Range< pair<Iter,Iter> > see below;

template<InputIterator Iter>
concept_map Range< const pair<Iter,Iter> > see below;

Add the following new section:

20.2.3 pair concept maps

template<InputIterator Iter>
concept_map Range< pair<Iter,Iter> >
{
    typedef Iter iterator;
    Iter begin( pair<Iter,Iter>& p ) { return p.first; }
    Iter end( pair<Iter,Iter>& p )   { return p.second; }
};

template<InputIterator Iter>
concept_map Range< const pair<Iter,Iter> >
{
    typedef Iter iterator;
    Iter begin( const pair<Iter,Iter>& p ) { return p.first; }
    Iter end( const pair<Iter,Iter>& p )   { return p.second; }
};

1 Note: Adapts a pair object of two iterators to the Range concept.

20.3 Header <tuple> synopsis

Add the following to the synopsis:

template<InputIterator Iter>
concept_map Range< tuple<Iter,Iter> > see below;

template<InputIterator Iter>
concept_map Range< const tuple<Iter,Iter> > see below;

Add the following new section:

20.3.1.6 tuple concept maps

template<InputIterator Iter>
concept_map Range< tuple<Iter,Iter> >
{
    typedef Iter iterator;
    Iter begin( tuple<Iter,Iter>& p ) { return std::get<0>(p); }
    Iter end( tuple<Iter,Iter>& p )   { return std::get<1>(p); }
};

template<InputIterator Iter>
concept_map Range< const tuple<Iter,Iter> >
{
    typedef Iter iterator;
    Iter begin( const tuple<Iter,Iter>& p ) { return std::get<0>(p); }
    Iter end( const tuple<Iter,Iter>& p )   { return std::get<1>(p); }
};

1 Note: Adapts a tuple object of two iterators to the Range concept.

23.1.4 Container concepts [container.concepts]

Add the following to the end of the ``<container_concepts>'' synopsis:

template<Container C>
concept_map Range<C> see below;

template<Container C>
concept_map Range<const C> see below;

23.1.4.3 Container concept maps [container.concepts.member]

Add the following to the end of [container.concepts.member]:

template<Container C>
concept_map Range<C>
{
    typedef C::iterator iterator;
    iterator begin( C& c ) { return Container<C>::begin(c); }
    iterator end( C& c )   { return Container<C>::end(c); }
};

template<Container C>
concept_map Range<const C>
{
    typedef C::const_iterator iterator;
    iterator begin( const C& c ) { return Container<C>::begin(c); }
    iterator end( const C& c )   { return Container<C>::end(c); }
};

13 Note: Adapts any type that meets the requirements of the Container concept to the Range concept.

26.5.1 Header <valarray> synopsis

Add the following to the synopsis:

template<class T>
concept_map Range< valarray<T> > see below;

template<class T>
concept_map Range< const valarray<T> > see below;

Add the following new section:

26.5.2.7 valarray concept maps

template<class T>
concept_map Range< valarray<T> >
{
    typedef unspecified type iterator;
    iterator begin( valarray<T>& a );
    iterator end( valarray<T>& a );
};

1 Note Adapts valarray to the Range concept.

  • typedef unspecified type iterator;

2 Requires: iterator shall meet the requirements of the RandomAccessIterator concept and iterator::reference shall equal T&.

  • iterator begin( valarray<T>& a );

3 Returns: an iterator referencing the first value in the numeric array.

  • iterator end( valarray<T>& a );

4 Returns: an iterator one past the last value in the numeric array.

template<class T>
concept_map Range< const valarray<T> >
{
    typedef unspecified type iterator;
    iterator begin( const valarray<T>& a );
    iterator end( const valarray<T>& a );
};
  • typedef unspecified type iterator;

5 Requires: iterator shall meet the requirements of the RandomAccessIterator and iterator::reference shall equal const T&.

  • iterator begin( const valarray<T>& a );

6 Returns: an iterator referencing the first value in the numeric array.

  • iterator end( const valarray<T>& a );

7 Returns: an iterator one past the last value in the numeric array.

28.4 Header <regex> synopsis

Add the following to the synopsis:

<BidirectionalIterator Iter>
concept_map Range< sub_match<Iter> > see below;

template<BidirectionalIterator Iter>
concept_map Range< const sub_match<Iter> > see below;

Add the following new section:

28.9.3 sub_match concept maps

<BidirectionalIterator Iter>
concept_map Range< sub_match<Iter> >
{
    typedef Iter iterator;
    Iter begin( sub_match<Iter>& p ) { return p.first; }
    Iter end( sub_match<Iter>& p )   { return p.second; }
};

template<BidirectionalIterator Iter>
concept_map Range< const sub_match<Iter> >
{
    typedef Iter iterator;
    Iter begin( const sub_match<Iter>& p ) { return p.first; }
    Iter end( const sub_match<Iter>& p )   { return p.second; }
};

1 Note: Adapts sub_match to the Range concept.