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