Wording for range-based for-loop

Author: Thorsten Ottosen
Contact: tottosen@dezide.com
Advisor:Lawrence Crowl
organizations:Dezide Aps
Date: 2006-02-18
Number:WG21/N1961 and J16/06-0031
Working Group:Core

Abstract

This paper provides wording for the new range-based for-loop previously described in n1868

Table of Contents

Introduction

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

The author would like to thank Lawrence Crowl for his help. Any mistake is the responsibility of the author.

6.5.4 The range-based for statement

1 The range-based for statement

for( type-specifier-seq simple-declarator : expression ) statement

is syntactically equivalent to

{
     auto&&  __rng(( expression ));
    
     for( auto __begin( std::begin(__rng) ), __end( std::end(__rng) );
          __begin != __end; ++__begin )
     {
         type-specifier-seq simple-declarator ( *__begin );
         statement
     }    
}

where __rng, __begin and __end are implementation-defined local variables.

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

24.2 Header <iterator> synopsis

Add the following to the end within namespace 'std':

template< class T >
auto range_begin( T&& t ) -> decltype( t.begin() );

template< class T >
T range_begin( const pair<T,T>& p ) ;

template< class T, size_t N >
T* range_begin( T (&array)[N] ) 

template< class T >
auto begin( T&& t ) -> decltype( range_begin(t) );

template< class T >
auto range_end( T&& t ) -> decltype( t.end() );

template< class T >
T range_end( const pair<T,T>& p );

template< class T, size_t N >
T* range_end( T (&array)[N] );

template< class T >
auto end( T&& t ) -> decltype( range_end(t) );

24.5.6 Range primitives

1 To support the range-based for statement (6.5.4), the library provides several utility functions.

24.5.6.1 Range operations

1 The functions range_begin() and range_begin() are intended to be overloaded for a user-defined type T in the namespace of T.

2 Within the standard library, the functions begin() and end() are always called qualified with the std namespace.

template< class T > auto range_begin( T&& t ) -> decltype( t.begin() );

3 Returns: t.begin()

template< class T > T range_begin( const pair<T,T>& p );

4 Returns: p.first

template< class T, size_t N > T* range_begin( T (&array)[N] );

5 Returns: array

template< class T > auto begin( T&& t ) -> decltype( range_begin(t) );

6 Returns: range_begin(t)

template< class T > auto range_end( T&& t ) -> decltype( t.end() );

7 Returns: t.end()

template< class T > T range_end( const pair<T,T>& p );

8 Returns: p.second

template< class T, size_t N > T* range_end( T (&array)[N] );

9 Returns: array + N

template< class T > auto end( T&& t ) -> decltype( range_end(t) );

10 Returns: range_end(t)

A Grammar summary

Add the following to section A.7 after the rule for 'declarator'

simple-declarator:
    declarator-id
    ptr-operator simple-declarator