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