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

source code of boost/boost/detail/is_incrementable.hpp