adl_conformance.cpp 4.8 KB

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