]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | ||
13 | namespace 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. | |
22 | namespace 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 | ||
38 | namespace is_incrementable_2 | |
39 | { | |
40 | is_incrementable_::tag operator++(is_incrementable_::any const&); | |
41 | is_incrementable_::tag operator++(is_incrementable_::any const&,int); | |
42 | } | |
43 | using namespace is_incrementable_2; | |
44 | ||
45 | namespace 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 | ||
105 | template<typename T> | |
106 | struct 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 | ||
112 | template<typename T> | |
113 | struct 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 |