1 // Boost.Range library
2 //
3 //  Copyright Thorsten Ottosen 2003-2004. Use, modification and
4 //  distribution is subject to the Boost Software License, Version
5 //  1.0. (See accompanying file LICENSE_1_0.txt or copy at
6 //  http://www.boost.org/LICENSE_1_0.txt)
7 //
8 // For more information, see http://www.boost.org/libs/range/
9 //
10 
11 #ifndef BOOST_RANGE_BEGIN_HPP
12 #define BOOST_RANGE_BEGIN_HPP
13 
14 #if defined(_MSC_VER)
15 # pragma once
16 #endif
17 
18 #include <boost/range/config.hpp>
19 
20 #include <boost/range/iterator.hpp>
21 #include <boost/config.hpp>
22 #include <boost/config/workaround.hpp>
23 
24 namespace boost
25 {
26 
27 #if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
28 namespace range_detail
29 {
30 #endif
31 
32     //////////////////////////////////////////////////////////////////////
33     // primary template
34     //////////////////////////////////////////////////////////////////////
35 
36     template< typename C >
37     BOOST_CONSTEXPR inline BOOST_DEDUCED_TYPENAME range_iterator<C>::type
range_begin(C & c)38     range_begin( C& c )
39     {
40         //
41         // If you get a compile-error here, it is most likely because
42         // you have not implemented range_begin() properly in
43         // the namespace of C
44         //
45         return c.begin();
46     }
47 
48     //////////////////////////////////////////////////////////////////////
49     // pair
50     //////////////////////////////////////////////////////////////////////
51 
52     template< typename Iterator >
range_begin(const std::pair<Iterator,Iterator> & p)53     BOOST_CONSTEXPR inline Iterator range_begin( const std::pair<Iterator,Iterator>& p )
54     {
55         return p.first;
56     }
57 
58     template< typename Iterator >
range_begin(std::pair<Iterator,Iterator> & p)59     BOOST_CONSTEXPR inline Iterator range_begin( std::pair<Iterator,Iterator>& p )
60     {
61         return p.first;
62     }
63 
64     //////////////////////////////////////////////////////////////////////
65     // array
66     //////////////////////////////////////////////////////////////////////
67 
68     //
69     // May this be discarded? Or is it needed for bad compilers?
70     //
71     template< typename T, std::size_t sz >
range_begin(const T (& a)[sz])72     BOOST_CONSTEXPR inline const T* range_begin( const T (&a)[sz] ) BOOST_NOEXCEPT
73     {
74         return a;
75     }
76 
77     template< typename T, std::size_t sz >
range_begin(T (& a)[sz])78     BOOST_CONSTEXPR inline T* range_begin( T (&a)[sz] ) BOOST_NOEXCEPT
79     {
80         return a;
81     }
82 
83 
84 #if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
85 } // namespace 'range_detail'
86 #endif
87 
88 // Use a ADL namespace barrier to avoid ambiguity with other unqualified
89 // calls. This is particularly important with C++0x encouraging
90 // unqualified calls to begin/end.
91 namespace range_adl_barrier
92 {
93 
94 template< class T >
95 #if !BOOST_WORKAROUND(BOOST_GCC, < 40700)
96 BOOST_CONSTEXPR
97 #endif
begin(T & r)98 inline BOOST_DEDUCED_TYPENAME range_iterator<T>::type begin( T& r )
99 {
100 #if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
101     using namespace range_detail;
102 #endif
103     return range_begin( r );
104 }
105 
106 template< class T >
107 #if !BOOST_WORKAROUND(BOOST_GCC, < 40700)
108 BOOST_CONSTEXPR
109 #endif
begin(const T & r)110 inline BOOST_DEDUCED_TYPENAME range_iterator<const T>::type begin( const T& r )
111 {
112 #if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
113     using namespace range_detail;
114 #endif
115     return range_begin( r );
116 }
117 
118     } // namespace range_adl_barrier
119 } // namespace boost
120 
121 namespace boost
122 {
123     namespace range_adl_barrier
124     {
125         template< class T >
126         inline BOOST_DEDUCED_TYPENAME range_iterator<const T>::type
const_begin(const T & r)127         const_begin( const T& r )
128         {
129             return boost::range_adl_barrier::begin( r );
130         }
131     } // namespace range_adl_barrier
132 
133     using namespace range_adl_barrier;
134 } // namespace boost
135 
136 #endif
137 
138