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

Generated on Wed Jan 21 15:32:09 2009 for SystemC by  doxygen 1.5.5