source: NonGTP/Boost/boost/iterator/is_lvalue_iterator.hpp @ 857

Revision 857, 4.0 KB checked in by igarcia, 19 years ago (diff)
Line 
1// Copyright David Abrahams 2003. Use, modification and distribution is
2// subject to the Boost 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#ifndef IS_LVALUE_ITERATOR_DWA2003112_HPP
5# define IS_LVALUE_ITERATOR_DWA2003112_HPP
6
7#include <boost/iterator.hpp>
8
9#include <boost/detail/workaround.hpp>
10#include <boost/detail/iterator.hpp>
11
12#include <boost/iterator/detail/any_conversion_eater.hpp>
13
14// should be the last #includes
15#include <boost/type_traits/detail/bool_trait_def.hpp>
16#include <boost/iterator/detail/config_def.hpp>
17
18#ifndef BOOST_NO_IS_CONVERTIBLE
19
20namespace boost {
21 
22namespace detail
23{
24#ifndef BOOST_NO_LVALUE_RETURN_DETECTION
25  // Calling lvalue_preserver( <expression>, 0 ) returns a reference
26  // to the expression's result if <expression> is an lvalue, or
27  // not_an_lvalue() otherwise.
28  struct not_an_lvalue {};
29 
30  template <class T>
31  T& lvalue_preserver(T&, int);
32 
33  template <class U>
34  not_an_lvalue lvalue_preserver(U const&, ...);
35 
36# define BOOST_LVALUE_PRESERVER(expr) detail::lvalue_preserver(expr,0)
37 
38#else
39 
40# define BOOST_LVALUE_PRESERVER(expr) expr
41 
42#endif
43
44  // Guts of is_lvalue_iterator.  Value is the iterator's value_type
45  // and the result is computed in the nested rebind template.
46  template <class Value>
47  struct is_lvalue_iterator_impl
48  {
49      // Eat implicit conversions so we don't report true for things
50      // convertible to Value const&
51      struct conversion_eater
52      {
53          conversion_eater(Value&);
54      };
55
56      static char tester(conversion_eater, int);
57      static char (& tester(any_conversion_eater, ...) )[2];
58   
59      template <class It>
60      struct rebind
61      {
62          static It& x;
63         
64          BOOST_STATIC_CONSTANT(
65              bool
66            , value = (
67                sizeof(
68                    is_lvalue_iterator_impl<Value>::tester(
69                        BOOST_LVALUE_PRESERVER(*x), 0
70                    )
71                ) == 1
72            )
73          );
74      };
75  };
76
77#undef BOOST_LVALUE_PRESERVER
78 
79  //
80  // void specializations to handle std input and output iterators
81  //
82  template <>
83  struct is_lvalue_iterator_impl<void>
84  {
85      template <class It>
86      struct rebind : boost::mpl::false_
87      {};
88  };
89
90#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
91  template <>
92  struct is_lvalue_iterator_impl<const void>
93  {
94      template <class It>
95      struct rebind : boost::mpl::false_
96      {};
97  };
98
99  template <>
100  struct is_lvalue_iterator_impl<volatile void>
101  {
102      template <class It>
103      struct rebind : boost::mpl::false_
104      {};
105  };
106
107  template <>
108  struct is_lvalue_iterator_impl<const volatile void>
109  {
110      template <class It>
111      struct rebind : boost::mpl::false_
112      {};
113  };
114#endif
115
116  //
117  // This level of dispatching is required for Borland.  We might save
118  // an instantiation by removing it for others.
119  //
120  template <class It>
121  struct is_readable_lvalue_iterator_impl
122    : is_lvalue_iterator_impl<
123          BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<It>::value_type const
124      >::template rebind<It>
125  {};
126
127  template <class It>
128  struct is_non_const_lvalue_iterator_impl
129    : is_lvalue_iterator_impl<
130          BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<It>::value_type
131      >::template rebind<It>
132  {};
133} // namespace detail
134
135// Define the trait with full mpl lambda capability and various broken
136// compiler workarounds
137BOOST_TT_AUX_BOOL_TRAIT_DEF1(
138    is_lvalue_iterator,T,::boost::detail::is_readable_lvalue_iterator_impl<T>::value)
139   
140BOOST_TT_AUX_BOOL_TRAIT_DEF1(
141    is_non_const_lvalue_iterator,T,::boost::detail::is_non_const_lvalue_iterator_impl<T>::value)
142   
143} // namespace boost
144
145#endif
146
147#include <boost/iterator/detail/config_undef.hpp>
148#include <boost/type_traits/detail/bool_trait_undef.hpp>
149
150#endif // IS_LVALUE_ITERATOR_DWA2003112_HPP
Note: See TracBrowser for help on using the repository browser.