source: NonGTP/Boost/boost/detail/is_incrementable.hpp @ 857

Revision 857, 3.5 KB checked in by igarcia, 18 years ago (diff)
Line 
1// Copyright David Abrahams 2004. 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_INCREMENTABLE_DWA200415_HPP
5# define IS_INCREMENTABLE_DWA200415_HPP
6
7# include <boost/type_traits/detail/bool_trait_def.hpp>
8# include <boost/type_traits/detail/template_arity_spec.hpp>
9# include <boost/type_traits/remove_cv.hpp>
10# include <boost/mpl/aux_/lambda_support.hpp>
11# include <boost/mpl/bool.hpp>
12# include <boost/detail/workaround.hpp>
13
14namespace boost { namespace detail {
15
16// is_incrementable<T> metafunction
17//
18// Requires: Given x of type T&, if the expression ++x is well-formed
19// it must have complete type; otherwise, it must neither be ambiguous
20// nor violate access.
21
22// This namespace ensures that ADL doesn't mess things up.
23namespace is_incrementable_
24{
25  // a type returned from operator++ when no increment is found in the
26  // type's own namespace
27  struct tag {};
28 
29  // any soaks up implicit conversions and makes the following
30  // operator++ less-preferred than any other such operator that
31  // might be found via ADL.
32  struct any { template <class T> any(T const&); };
33
34  // This is a last-resort operator++ for when none other is found
35# if BOOST_WORKAROUND(__GNUC__, == 4) && __GNUC_MINOR__ == 0 && __GNUC_PATCHLEVEL__ == 2
36 
37}
38
39namespace is_incrementable_2
40{
41  is_incrementable_::tag operator++(is_incrementable_::any const&);
42  is_incrementable_::tag operator++(is_incrementable_::any const&,int);
43}
44using namespace is_incrementable_2;
45
46namespace is_incrementable_
47{
48 
49# else
50 
51  tag operator++(any const&);
52  tag operator++(any const&,int);
53 
54# endif
55
56# if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3202)) \
57    || BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
58#  define BOOST_comma(a,b) (a)
59# else
60  // In case an operator++ is found that returns void, we'll use ++x,0
61  tag operator,(tag,int); 
62#  define BOOST_comma(a,b) (a,b)
63# endif
64 
65  // two check overloads help us identify which operator++ was picked
66  char (& check(tag) )[2];
67 
68  template <class T>
69  char check(T const&);
70 
71
72  template <class T>
73  struct impl
74  {
75      static typename boost::remove_cv<T>::type& x;
76
77      BOOST_STATIC_CONSTANT(
78          bool
79        , value = sizeof(is_incrementable_::check(BOOST_comma(++x,0))) == 1
80      );
81  };
82
83  template <class T>
84  struct postfix_impl
85  {
86      static typename boost::remove_cv<T>::type& x;
87
88      BOOST_STATIC_CONSTANT(
89          bool
90        , value = sizeof(is_incrementable_::check(BOOST_comma(x++,0))) == 1
91      );
92  };
93}
94
95# undef BOOST_comma
96
97template<typename T>
98struct is_incrementable
99BOOST_TT_AUX_BOOL_C_BASE(::boost::detail::is_incrementable_::impl<T>::value)
100{
101    BOOST_TT_AUX_BOOL_TRAIT_VALUE_DECL(::boost::detail::is_incrementable_::impl<T>::value)
102    BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_incrementable,(T))
103};
104
105template<typename T>
106struct is_postfix_incrementable
107BOOST_TT_AUX_BOOL_C_BASE(::boost::detail::is_incrementable_::impl<T>::value)
108{
109    BOOST_TT_AUX_BOOL_TRAIT_VALUE_DECL(::boost::detail::is_incrementable_::postfix_impl<T>::value)
110    BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_postfix_incrementable,(T))
111};
112
113} // namespace detail
114
115BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(1, ::boost::detail::is_incrementable)
116BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(1, ::boost::detail::is_postfix_incrementable)
117
118} // namespace boost
119
120
121#endif // IS_INCREMENTABLE_DWA200415_HPP
Note: See TracBrowser for help on using the repository browser.