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_END_HPP
12 #define BOOST_RANGE_END_HPP
13 
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
15 # pragma once
16 #endif
17 
18 #include <boost/type_traits/remove_const.hpp>
19 #include <boost/range/config.hpp>
20 
21 #ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
22 #include <boost/range/detail/end.hpp>
23 #else
24 
25 #include <boost/range/detail/implementation_help.hpp>
26 #include <boost/range/iterator.hpp>
27 #include <boost/range/const_iterator.hpp>
28 
29 namespace boost
30 {
31 
32 #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && \
33     !BOOST_WORKAROUND(__GNUC__, < 3) \
34     /**/
35 namespace range_detail
36 {
37 #endif
38 
39         //////////////////////////////////////////////////////////////////////
40         // primary template
41         //////////////////////////////////////////////////////////////////////
42 
43         template< typename C >
44         inline BOOST_DEDUCED_TYPENAME range_const_iterator<C>::type
boost_range_end(const C & c)45         boost_range_end( const C& c )
46         {
47             return c.end();
48         }
49 
50         template< typename C >
51                 inline BOOST_DEDUCED_TYPENAME range_iterator<
52                                         typename remove_const<C>::type >::type
boost_range_end(C & c)53         boost_range_end( C& c )
54         {
55             return c.end();
56         }
57 
58         //////////////////////////////////////////////////////////////////////
59         // pair
60         //////////////////////////////////////////////////////////////////////
61 
62         template< typename Iterator >
boost_range_end(const std::pair<Iterator,Iterator> & p)63         inline Iterator boost_range_end( const std::pair<Iterator,Iterator>& p )
64         {
65             return p.second;
66         }
67 
68         template< typename Iterator >
boost_range_end(std::pair<Iterator,Iterator> & p)69         inline Iterator boost_range_end( std::pair<Iterator,Iterator>& p )
70         {
71             return p.second;
72         }
73 
74         //////////////////////////////////////////////////////////////////////
75         // array
76         //////////////////////////////////////////////////////////////////////
77 
78         template< typename T, std::size_t sz >
boost_range_end(const T (& array)[sz])79         inline const T* boost_range_end( const T (&array)[sz] )
80         {
81             return range_detail::array_end<T,sz>( array );
82         }
83 
84         template< typename T, std::size_t sz >
boost_range_end(T (& array)[sz])85         inline T* boost_range_end( T (&array)[sz] )
86         {
87             return range_detail::array_end<T,sz>( array );
88         }
89 
90         //////////////////////////////////////////////////////////////////////
91         // string
92         //////////////////////////////////////////////////////////////////////
93 
94 #if 1 || BOOST_WORKAROUND(__MWERKS__, <= 0x3204 ) || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
95 // CW up to 9.3 and borland have troubles with function ordering
boost_range_end(char * s)96         inline char* boost_range_end( char* s )
97         {
98             return range_detail::str_end( s );
99         }
100 
boost_range_end(wchar_t * s)101         inline wchar_t* boost_range_end( wchar_t* s )
102         {
103             return range_detail::str_end( s );
104         }
105 
boost_range_end(const char * s)106         inline const char* boost_range_end( const char* s )
107         {
108             return range_detail::str_end( s );
109         }
110 
boost_range_end(const wchar_t * s)111         inline const wchar_t* boost_range_end( const wchar_t* s )
112         {
113             return range_detail::str_end( s );
114         }
115 #else
boost_range_end(char * & s)116         inline char* boost_range_end( char*& s )
117         {
118             return range_detail::str_end( s );
119         }
120 
boost_range_end(wchar_t * & s)121         inline wchar_t* boost_range_end( wchar_t*& s )
122         {
123             return range_detail::str_end( s );
124         }
125 
boost_range_end(const char * & s)126         inline const char* boost_range_end( const char*& s )
127         {
128             return range_detail::str_end( s );
129         }
130 
boost_range_end(const wchar_t * & s)131         inline const wchar_t* boost_range_end( const wchar_t*& s )
132         {
133             return range_detail::str_end( s );
134         }
135 #endif
136 
137 #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && \
138     !BOOST_WORKAROUND(__GNUC__, < 3) \
139     /**/
140 } // namespace 'range_detail'
141 #endif
142 
143 template< class T >
144 inline BOOST_DEDUCED_TYPENAME range_iterator<
end(T & r)145                 typename remove_const<T>::type >::type end( T& r )
146 {
147 #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && \
148     !BOOST_WORKAROUND(__GNUC__, < 3) \
149     /**/
150     using namespace range_detail;
151 #endif
152     return boost_range_end( r );
153 }
154 
155 template< class T >
end(const T & r)156 inline BOOST_DEDUCED_TYPENAME range_const_iterator<T>::type end( const T& r )
157 {
158 #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && \
159     !BOOST_WORKAROUND(__GNUC__, < 3) \
160     /**/
161     using namespace range_detail;
162 #endif
163     return boost_range_end( r );
164 }
165 
166 
167 
168 #if BOOST_WORKAROUND(__MWERKS__, <= 0x3003 ) || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
169 // BCB and CW are not able to overload pointer when class overloads are also available.
170 template<>
end(const char * & r)171 inline range_const_iterator<const char*>::type end<const char*>( const char*& r )
172 {
173     return range_detail::str_end( r );
174 }
175 
176 template<>
end(const wchar_t * & r)177 inline range_const_iterator<const wchar_t*>::type end<const wchar_t*>( const wchar_t*& r )
178 {
179     return range_detail::str_end( r );
180 }
181 
182 #endif
183 
184 } // namespace 'boost'
185 
186 
187 
188 #endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
189 
190 
191 namespace boost
192 {
193     template< class T >
194     inline BOOST_DEDUCED_TYPENAME range_const_iterator<T>::type
const_end(const T & r)195     const_end( const T& r )
196     {
197         return end( r );
198     }
199 }
200 
201 #endif
202