| 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 | #include <boost/detail/workaround.hpp> | 
|---|
| 12 |  | 
|---|
| 13 | #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) | 
|---|
| 14 | #  pragma warn -8091 // supress warning in Boost.Test | 
|---|
| 15 | #  pragma warn -8057 // unused argument argc/argv in Boost.Test | 
|---|
| 16 | #endif | 
|---|
| 17 |  | 
|---|
| 18 | #include <boost/test/unit_test.hpp> | 
|---|
| 19 | #include <boost/test/test_tools.hpp> | 
|---|
| 20 |  | 
|---|
| 21 | enum adl_types | 
|---|
| 22 | { | 
|---|
| 23 |     unused, | 
|---|
| 24 |     boost_namespace, | 
|---|
| 25 |     templated_namespace, | 
|---|
| 26 |     non_templated_namespace, | 
|---|
| 27 |     global_namespace | 
|---|
| 28 | }; | 
|---|
| 29 |  | 
|---|
| 30 | namespace boost | 
|---|
| 31 | { | 
|---|
| 32 |     namespace range_detail | 
|---|
| 33 |     { | 
|---|
| 34 |         template< class Range > | 
|---|
| 35 |         inline typename Range::iterator begin( Range& r ) | 
|---|
| 36 |         { | 
|---|
| 37 |             return boost_namespace;   | 
|---|
| 38 |         } | 
|---|
| 39 |          | 
|---|
| 40 |         template< class Range > | 
|---|
| 41 |         inline typename Range::iterator begin( const Range& r ) | 
|---|
| 42 |         { | 
|---|
| 43 |             return boost_namespace;   | 
|---|
| 44 |         } | 
|---|
| 45 |  | 
|---|
| 46 |     } | 
|---|
| 47 |      | 
|---|
| 48 |     template< class Range > | 
|---|
| 49 |     inline typename Range::iterator begin( Range& r ) | 
|---|
| 50 |     { | 
|---|
| 51 |         using range_detail::begin; // create ADL hook | 
|---|
| 52 |         return begin( r ); | 
|---|
| 53 |     } | 
|---|
| 54 |      | 
|---|
| 55 |     template< class Range > | 
|---|
| 56 |     inline typename Range::iterator begin( const Range& r ) | 
|---|
| 57 |     { | 
|---|
| 58 |         using range_detail::begin; // create ADL hook | 
|---|
| 59 |         return begin( r ); | 
|---|
| 60 |     } | 
|---|
| 61 | } | 
|---|
| 62 |  | 
|---|
| 63 |  | 
|---|
| 64 | namespace find_templated | 
|---|
| 65 | { | 
|---|
| 66 |     template< class T > | 
|---|
| 67 |     struct range | 
|---|
| 68 |     { | 
|---|
| 69 |         typedef adl_types iterator; | 
|---|
| 70 |  | 
|---|
| 71 |         range()                { /* allow const objects */ } | 
|---|
| 72 |         iterator begin()       { return unused; } | 
|---|
| 73 |         iterator begin() const { return unused; } | 
|---|
| 74 |         iterator end()         { return unused; } | 
|---|
| 75 |         iterator end() const   { return unused; } | 
|---|
| 76 |     }; | 
|---|
| 77 |          | 
|---|
| 78 |     // | 
|---|
| 79 |     // A fully generic version here will create | 
|---|
| 80 |     // ambiguity. | 
|---|
| 81 |     // | 
|---|
| 82 |     template< class T > | 
|---|
| 83 |     inline typename range<T>::iterator begin( range<T>& r ) | 
|---|
| 84 |     { | 
|---|
| 85 |         return templated_namespace; | 
|---|
| 86 |     } | 
|---|
| 87 |      | 
|---|
| 88 |     template< class T > | 
|---|
| 89 |     inline typename range<T>::iterator begin( const range<T>& r ) | 
|---|
| 90 |     { | 
|---|
| 91 |         return templated_namespace; | 
|---|
| 92 |     } | 
|---|
| 93 |  | 
|---|
| 94 | } | 
|---|
| 95 |  | 
|---|
| 96 | namespace find_non_templated | 
|---|
| 97 | { | 
|---|
| 98 |     struct range | 
|---|
| 99 |     { | 
|---|
| 100 |         typedef adl_types iterator; | 
|---|
| 101 |          | 
|---|
| 102 |         range()                { /* allow const objects */ } | 
|---|
| 103 |         iterator begin()       { return unused; } | 
|---|
| 104 |         iterator begin() const { return unused; } | 
|---|
| 105 |         iterator end()         { return unused; } | 
|---|
| 106 |         iterator end() const   { return unused; } | 
|---|
| 107 |     }; | 
|---|
| 108 |      | 
|---|
| 109 |     inline range::iterator begin( range& r ) | 
|---|
| 110 |     { | 
|---|
| 111 |         return non_templated_namespace; | 
|---|
| 112 |     } | 
|---|
| 113 |      | 
|---|
| 114 |      | 
|---|
| 115 |     inline range::iterator begin( const range& r ) | 
|---|
| 116 |     { | 
|---|
| 117 |         return non_templated_namespace; | 
|---|
| 118 |     } | 
|---|
| 119 | } | 
|---|
| 120 |  | 
|---|
| 121 | struct range | 
|---|
| 122 | { | 
|---|
| 123 |     typedef adl_types iterator; | 
|---|
| 124 |  | 
|---|
| 125 |     range()                { /* allow const objects */ } | 
|---|
| 126 |     iterator begin()       { return unused; } | 
|---|
| 127 |     iterator begin() const { return unused; } | 
|---|
| 128 |     iterator end()         { return unused; } | 
|---|
| 129 |     iterator end() const   { return unused; } | 
|---|
| 130 | }; | 
|---|
| 131 |  | 
|---|
| 132 | inline range::iterator begin( range& r ) | 
|---|
| 133 | { | 
|---|
| 134 |     return global_namespace; | 
|---|
| 135 | }    | 
|---|
| 136 |  | 
|---|
| 137 | inline range::iterator begin( const range& r ) | 
|---|
| 138 | { | 
|---|
| 139 |     return global_namespace; | 
|---|
| 140 | }    | 
|---|
| 141 |  | 
|---|
| 142 | void check_adl_conformance() | 
|---|
| 143 | { | 
|---|
| 144 |     find_templated::range<int>       r; | 
|---|
| 145 |     const find_templated::range<int> r2; | 
|---|
| 146 |     find_non_templated::range        r3; | 
|---|
| 147 |     const find_non_templated::range  r4; | 
|---|
| 148 |     range                            r5; | 
|---|
| 149 |     const range                      r6; | 
|---|
| 150 |      | 
|---|
| 151 |     // | 
|---|
| 152 |     // Notice how ADL kicks in even when we have qualified  | 
|---|
| 153 |     // notation! | 
|---|
| 154 |     // | 
|---|
| 155 |      | 
|---|
| 156 |  | 
|---|
| 157 |     BOOST_CHECK( boost::begin( r )  != boost_namespace ); | 
|---|
| 158 |     BOOST_CHECK( boost::begin( r2 ) != boost_namespace ); | 
|---|
| 159 |     BOOST_CHECK( boost::begin( r3 ) != boost_namespace ); | 
|---|
| 160 |     BOOST_CHECK( boost::begin( r4 ) != boost_namespace ); | 
|---|
| 161 |     BOOST_CHECK( boost::begin( r5 ) != boost_namespace ); | 
|---|
| 162 |     BOOST_CHECK( boost::begin( r6 ) != boost_namespace ); | 
|---|
| 163 |      | 
|---|
| 164 |     BOOST_CHECK_EQUAL( boost::begin( r ), templated_namespace ) ; | 
|---|
| 165 |     BOOST_CHECK_EQUAL( boost::begin( r2 ), templated_namespace ); | 
|---|
| 166 |     BOOST_CHECK_EQUAL( boost::begin( r3 ), non_templated_namespace ); | 
|---|
| 167 |     BOOST_CHECK_EQUAL( boost::begin( r4 ), non_templated_namespace ); | 
|---|
| 168 |     BOOST_CHECK_EQUAL( boost::begin( r5 ), global_namespace ); | 
|---|
| 169 |     BOOST_CHECK_EQUAL( boost::begin( r6 ), global_namespace ); | 
|---|
| 170 | } | 
|---|
| 171 |  | 
|---|
| 172 | #include <boost/test/included/unit_test_framework.hpp>  | 
|---|
| 173 |  | 
|---|
| 174 | using boost::unit_test_framework::test_suite; | 
|---|
| 175 |  | 
|---|
| 176 | test_suite* init_unit_test_suite( int argc, char* argv[] ) | 
|---|
| 177 | { | 
|---|
| 178 |     test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" ); | 
|---|
| 179 |  | 
|---|
| 180 |     test->add( BOOST_TEST_CASE( &check_adl_conformance ) ); | 
|---|
| 181 |  | 
|---|
| 182 |     return test; | 
|---|
| 183 | } | 
|---|
| 184 |  | 
|---|
| 185 |  | 
|---|