is_incrementable.hpp
Go to the documentation of this file.
00001 // Copyright David Abrahams 2004. Use, modification and distribution is
00002 // subject to the Boost Software License, Version 1.0. (See accompanying
00003 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
00004 #ifndef IS_INCREMENTABLE_DWA200415_HPP
00005 # define IS_INCREMENTABLE_DWA200415_HPP
00006 
00007 # include <boost/type_traits/detail/template_arity_spec.hpp>
00008 # include <boost/type_traits/remove_cv.hpp>
00009 # include <boost/mpl/aux_/lambda_support.hpp>
00010 # include <boost/mpl/bool.hpp>
00011 # include <boost/detail/workaround.hpp>
00012 
00013 // Must be the last include
00014 # include <boost/type_traits/detail/bool_trait_def.hpp>
00015 
00016 namespace boost { namespace detail { 
00017 
00018 // is_incrementable<T> metafunction
00019 //
00020 // Requires: Given x of type T&, if the expression ++x is well-formed
00021 // it must have complete type; otherwise, it must neither be ambiguous
00022 // nor violate access.
00023 
00024 // This namespace ensures that ADL doesn't mess things up.
00025 namespace is_incrementable_
00026 {
00027   // a type returned from operator++ when no increment is found in the
00028   // type's own namespace
00029   struct tag {};
00030   
00031   // any soaks up implicit conversions and makes the following
00032   // operator++ less-preferred than any other such operator that
00033   // might be found via ADL.
00034   struct any { template <class T> any(T const&); };
00035 
00036   // This is a last-resort operator++ for when none other is found
00037 # if BOOST_WORKAROUND(__GNUC__, == 4) && __GNUC_MINOR__ == 0 && __GNUC_PATCHLEVEL__ == 2
00038   
00039 }
00040 
00041 namespace is_incrementable_2
00042 {
00043   is_incrementable_::tag operator++(is_incrementable_::any const&);
00044   is_incrementable_::tag operator++(is_incrementable_::any const&,int);
00045 }
00046 using namespace is_incrementable_2;
00047 
00048 namespace is_incrementable_
00049 {
00050   
00051 # else
00052   
00053   tag operator++(any const&);
00054   tag operator++(any const&,int);
00055   
00056 # endif 
00057 
00058 # if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3202)) \
00059     || BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
00060 #  define BOOST_comma(a,b) (a)
00061 # else 
00062   // In case an operator++ is found that returns void, we'll use ++x,0
00063   tag operator,(tag,int);  
00064 #  define BOOST_comma(a,b) (a,b)
00065 # endif 
00066   
00067   // two check overloads help us identify which operator++ was picked
00068   char (& check(tag) )[2];
00069   
00070   template <class T>
00071   char check(T const&);
00072   
00073 
00074   template <class T>
00075   struct impl
00076   {
00077       static typename boost::remove_cv<T>::type& x;
00078 
00079       BOOST_STATIC_CONSTANT(
00080           bool
00081         , value = sizeof(is_incrementable_::check(BOOST_comma(++x,0))) == 1
00082       );
00083   };
00084 
00085   template <class T>
00086   struct postfix_impl
00087   {
00088       static typename boost::remove_cv<T>::type& x;
00089 
00090       BOOST_STATIC_CONSTANT(
00091           bool
00092         , value = sizeof(is_incrementable_::check(BOOST_comma(x++,0))) == 1
00093       );
00094   };
00095 }
00096 
00097 # undef BOOST_comma
00098 
00099 template<typename T> 
00100 struct is_incrementable 
00101 BOOST_TT_AUX_BOOL_C_BASE(::boost::detail::is_incrementable_::impl<T>::value)
00102 { 
00103     BOOST_TT_AUX_BOOL_TRAIT_VALUE_DECL(::boost::detail::is_incrementable_::impl<T>::value)
00104     BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_incrementable,(T))
00105 };
00106 
00107 template<typename T> 
00108 struct is_postfix_incrementable 
00109 BOOST_TT_AUX_BOOL_C_BASE(::boost::detail::is_incrementable_::impl<T>::value)
00110 { 
00111     BOOST_TT_AUX_BOOL_TRAIT_VALUE_DECL(::boost::detail::is_incrementable_::postfix_impl<T>::value)
00112     BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_postfix_incrementable,(T))
00113 };
00114 
00115 } // namespace detail
00116 
00117 BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(1, ::boost::detail::is_incrementable)
00118 BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(1, ::boost::detail::is_postfix_incrementable)
00119 
00120 } // namespace boost
00121 
00122 # include <boost/type_traits/detail/bool_trait_undef.hpp>
00123 
00124 #endif // IS_INCREMENTABLE_DWA200415_HPP


appl
Author(s): petercai
autogenerated on Tue Jan 7 2014 11:02:29