Ticket #2009: x.cpp

File x.cpp, 2.3 KB (added by Dave Abrahams, 14 years ago)
Line 
1// Copyright David Abrahams 2008. Distributed under the Boost
2// Software License, Version 1.0. (See accompanying
3// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
4#include "boost/utility/enable_if.hpp"
5#include "boost/mpl/bool.hpp"
6
7namespace boost
8{
9 template <class T>
10 struct range_iterator
11 {
12 typedef typename T::iterator type;
13 };
14
15 template <class T>
16 struct range_iterator<T const>
17 : range_iterator<T>
18 {};
19}
20
21namespace my
22{
23 struct range1 { range1() {} };
24 int* range_begin(range1 const& r) { return 0; }
25
26 struct range2
27 {
28 range2() {}
29
30 typedef char* iterator;
31 char* begin() const { return 0; }
32 };
33}
34
35namespace boost
36{
37 template <>
38 struct range_iterator<my::range1>
39 {
40 typedef int* type;
41 };
42}
43
44namespace boost
45{
46 namespace range_detail
47 {
48 typedef char (&false_)[2];
49 typedef char true_;
50
51 struct not_overloaded {};
52 not_overloaded operator,(not_overloaded,int);
53
54 template <class T>
55 not_overloaded range_begin(T const&);
56
57 template <class T>
58 true_ is_overloaded(T const&);
59
60 false_ is_overloaded(not_overloaded);
61
62 template <class T>
63 T& make();
64
65 template <class R>
66 struct range_begin_overloaded
67 : mpl::bool_< (sizeof(range_detail::is_overloaded(
68 (range_begin(make<R const>()),3)
69 ))) == 1 >
70 {
71 };
72 }
73
74 namespace begin_
75 {
76 template <class R>
77 typename lazy_disable_if<range_detail::range_begin_overloaded<R>, range_iterator<R> >::type
78 range_begin(R& r) { return r.begin(); }
79
80 template <class R>
81 typename lazy_disable_if<range_detail::range_begin_overloaded<R>, range_iterator<R> >::type
82 range_begin(R const& r) { return r.begin(); }
83
84 template <class R>
85 typename range_iterator<R>::type begin(R& r) { return range_begin(r); }
86
87 template <class R>
88 typename range_iterator<R>::type begin(R const& r) { return range_begin(r); }
89 }
90 using begin_::begin;
91};
92
93
94namespace your
95{
96
97 int* z0 = boost::begin(my::range1());
98
99 my::range1 x0;
100 int* z1 = boost::begin(x0);
101
102 my::range1 const x1;
103 int* z2 = boost::begin(x1);
104
105 char* w0 = boost::begin(my::range2());
106
107 my::range2 y0;
108 char* w1 = boost::begin(y0);
109
110 my::range2 const y1;
111 char* w2 = boost::begin(y1);
112
113}
114
115int main() {}