Chris@16: // Copyright David Abrahams 2004. Use, modification and distribution is Chris@16: // subject to the Boost Software License, Version 1.0. (See accompanying Chris@16: // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: #ifndef IS_INCREMENTABLE_DWA200415_HPP Chris@16: # define IS_INCREMENTABLE_DWA200415_HPP Chris@16: Chris@16: # include Chris@16: # include Chris@16: # include Chris@16: # include Chris@16: # include Chris@16: Chris@16: // Must be the last include Chris@16: # include Chris@16: Chris@16: namespace boost { namespace detail { Chris@16: Chris@16: // is_incrementable metafunction Chris@16: // Chris@16: // Requires: Given x of type T&, if the expression ++x is well-formed Chris@16: // it must have complete type; otherwise, it must neither be ambiguous Chris@16: // nor violate access. Chris@16: Chris@16: // This namespace ensures that ADL doesn't mess things up. Chris@16: namespace is_incrementable_ Chris@16: { Chris@16: // a type returned from operator++ when no increment is found in the Chris@16: // type's own namespace Chris@16: struct tag {}; Chris@16: Chris@16: // any soaks up implicit conversions and makes the following Chris@16: // operator++ less-preferred than any other such operator that Chris@16: // might be found via ADL. Chris@16: struct any { template any(T const&); }; Chris@16: Chris@16: // This is a last-resort operator++ for when none other is found Chris@16: # if BOOST_WORKAROUND(__GNUC__, == 4) && __GNUC_MINOR__ == 0 && __GNUC_PATCHLEVEL__ == 2 Chris@16: Chris@16: } Chris@16: Chris@16: namespace is_incrementable_2 Chris@16: { Chris@16: is_incrementable_::tag operator++(is_incrementable_::any const&); Chris@16: is_incrementable_::tag operator++(is_incrementable_::any const&,int); Chris@16: } Chris@16: using namespace is_incrementable_2; Chris@16: Chris@16: namespace is_incrementable_ Chris@16: { Chris@16: Chris@16: # else Chris@16: Chris@16: tag operator++(any const&); Chris@16: tag operator++(any const&,int); Chris@16: Chris@16: # endif Chris@16: Chris@101: # if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3202)) Chris@16: # define BOOST_comma(a,b) (a) Chris@16: # else Chris@16: // In case an operator++ is found that returns void, we'll use ++x,0 Chris@16: tag operator,(tag,int); Chris@16: # define BOOST_comma(a,b) (a,b) Chris@16: # endif Chris@16: Chris@16: # if defined(BOOST_MSVC) Chris@16: # pragma warning(push) Chris@16: # pragma warning(disable:4913) // Warning about operator, Chris@16: # endif Chris@16: Chris@16: // two check overloads help us identify which operator++ was picked Chris@16: char (& check_(tag) )[2]; Chris@16: Chris@16: template Chris@16: char check_(T const&); Chris@16: Chris@16: Chris@16: template Chris@16: struct impl Chris@16: { Chris@16: static typename boost::remove_cv::type& x; Chris@16: Chris@16: BOOST_STATIC_CONSTANT( Chris@16: bool Chris@16: , value = sizeof(is_incrementable_::check_(BOOST_comma(++x,0))) == 1 Chris@16: ); Chris@16: }; Chris@16: Chris@16: template Chris@16: struct postfix_impl Chris@16: { Chris@16: static typename boost::remove_cv::type& x; Chris@16: Chris@16: BOOST_STATIC_CONSTANT( Chris@16: bool Chris@16: , value = sizeof(is_incrementable_::check_(BOOST_comma(x++,0))) == 1 Chris@16: ); Chris@16: }; Chris@16: Chris@16: # if defined(BOOST_MSVC) Chris@16: # pragma warning(pop) Chris@16: # endif Chris@16: Chris@16: } Chris@16: Chris@16: # undef BOOST_comma Chris@16: Chris@16: template Chris@16: struct is_incrementable Chris@16: BOOST_TT_AUX_BOOL_C_BASE(::boost::detail::is_incrementable_::impl::value) Chris@16: { Chris@16: BOOST_TT_AUX_BOOL_TRAIT_VALUE_DECL(::boost::detail::is_incrementable_::impl::value) Chris@16: BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_incrementable,(T)) Chris@16: }; Chris@16: Chris@16: template Chris@16: struct is_postfix_incrementable Chris@101: BOOST_TT_AUX_BOOL_C_BASE(::boost::detail::is_incrementable_::postfix_impl::value) Chris@16: { Chris@16: BOOST_TT_AUX_BOOL_TRAIT_VALUE_DECL(::boost::detail::is_incrementable_::postfix_impl::value) Chris@16: BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_postfix_incrementable,(T)) Chris@16: }; Chris@16: Chris@16: } // namespace detail Chris@16: Chris@16: BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(1, ::boost::detail::is_incrementable) Chris@16: BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(1, ::boost::detail::is_postfix_incrementable) Chris@16: Chris@16: } // namespace boost Chris@16: Chris@16: # include Chris@16: Chris@16: #endif // IS_INCREMENTABLE_DWA200415_HPP