Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/boost/phoenix/function/lazy_smart.hpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 ////////////////////////////////////////////////////////////////////////////
0002 // lazy smart.hpp
0003 //
0004 // Build lazy functoid traits for Phoenix equivalents for FC++
0005 //
0006 // These are equivalents of the Boost FC++ functoid traits in smart.hpp
0007 //
0008 // I have copied the versions for zero, one, two and three arguments.
0009 //
0010 /*=============================================================================
0011     Copyright (c) 2000-2003 Brian McNamara and Yannis Smaragdakis
0012     Copyright (c) 2001-2007 Joel de Guzman
0013     Copyright (c) 2015 John Fletcher
0014 
0015     Distributed under the Boost Software License, Version 1.0. (See accompanying
0016     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0017 ==============================================================================*/
0018 
0019 #ifndef BOOST_PHOENIX_FUNCTION_LAZY_SMART
0020 #define BOOST_PHOENIX_FUNCTION_LAZY_SMART
0021 
0022 namespace boost {
0023     namespace phoenix {
0024       namespace fcpp {
0025 
0026 //////////////////////////////////////////////////////////////////////
0027 // Feature: Smartness
0028 //////////////////////////////////////////////////////////////////////
0029 // If F is smart, then we can refer to these entities:
0030 //
0031 //    functoid_traits<F>::template accepts<N>::args
0032 //       A bool which says whether F can accept N arguments
0033 //
0034 //    functoid_traits<F>::max_args
0035 //       An int which says what the most arguments F can accept is
0036 //
0037 //    functoid_traits<F>::template ensure_accepts<N>::args()
0038 //       A no-op call that compiles only if F can accept N args
0039 //
0040 // We use traits so that if you happen to ask a non-smart functoid these
0041 // questions, you will hopefully get a literate error message.
0042 
0043 struct SmartFunctoid {};
0044 
0045 // We add crazy identifiers to ensure that users don't accidentally talk
0046 // to functoids directly; they should always be going through the traits
0047 // class to ask for info.
0048 struct smart_functoid0 : public SmartFunctoid {
0049    template <class Dummy, int i> struct crazy_accepts {
0050       static const bool args = false;
0051    };
0052    template <class Dummy> struct crazy_accepts<Dummy,0> {
0053       static const bool args = true;
0054    };
0055    static const int crazy_max_args = 0;
0056 };
0057 
0058 struct smart_functoid1 : public SmartFunctoid {
0059    template <class Dummy, int i> struct crazy_accepts {
0060       static const bool args = false;
0061    };
0062    template <class Dummy> struct crazy_accepts<Dummy,1> {
0063       static const bool args = true;
0064    };
0065    static const int crazy_max_args = 1;
0066 };
0067 
0068 struct smart_functoid2 : public SmartFunctoid {
0069    template <class Dummy, int i> struct crazy_accepts {
0070       static const bool args = false;
0071    };
0072    template <class Dummy> struct crazy_accepts<Dummy,1> {
0073       static const bool args = true;
0074    };
0075    template <class Dummy> struct crazy_accepts<Dummy,2> {
0076       static const bool args = true;
0077    };
0078    static const int crazy_max_args = 2;
0079 };
0080 
0081 struct smart_functoid3 : public SmartFunctoid {
0082    template <class Dummy, int i> struct crazy_accepts {
0083       static const bool args = false;
0084    };
0085    template <class Dummy> struct crazy_accepts<Dummy,1> {
0086       static const bool args = true;
0087    };
0088    template <class Dummy> struct crazy_accepts<Dummy,2> {
0089       static const bool args = true;
0090    };
0091    template <class Dummy> struct crazy_accepts<Dummy,3> {
0092       static const bool args = true;
0093    };
0094    static const int crazy_max_args = 3;
0095 };
0096 
0097 
0098 namespace impl {
0099    template <class F, bool b> struct NeededASmartFunctoidButInsteadGot {};
0100    template <class F> struct NeededASmartFunctoidButInsteadGot<F,true> {
0101       typedef F type;
0102    };
0103    template <bool b> struct Ensure;
0104    template <> struct Ensure<true> {};
0105 } // end namespace impl
0106 
0107 template <class MaybeASmartFunctoid>
0108 struct functoid_traits {
0109   typedef typename boost::remove_reference<MaybeASmartFunctoid>::type MaybeASmartFunctoidT;
0110    typedef
0111       typename impl::NeededASmartFunctoidButInsteadGot<MaybeASmartFunctoidT,
0112          boost::is_base_and_derived<SmartFunctoid,
0113          MaybeASmartFunctoidT>::value>::type F;
0114       template <int i> struct accepts {
0115       static const bool args = F::template crazy_accepts<int,i>::args;
0116    };
0117    template <int i> struct ensure_accepts {
0118       static const bool ok = F::template crazy_accepts<int,i>::args;
0119       inline static void args() { (void) impl::Ensure<ok>(); }
0120    };
0121    static const int max_args = F::crazy_max_args;
0122 };
0123 
0124 // These can be used to make functoids smart without having to alter
0125 // code elsewhere. These are used instead of boost::phoenix::function
0126 // to declare the object.
0127 template <typename F>
0128 struct smart_function0 : public smart_functoid0,
0129                          public boost::phoenix::function<F>
0130 { };
0131 
0132 template <typename F>
0133 struct smart_function1 : public smart_functoid1,
0134                          public boost::phoenix::function<F>
0135 {
0136   typedef F type;
0137 };
0138 
0139 template <typename F>
0140 struct smart_function2 : public smart_functoid2,
0141                          public boost::phoenix::function<F>
0142 { };
0143 
0144 template <typename F>
0145 struct smart_function3 : public smart_functoid3,
0146                          public boost::phoenix::function<F>
0147 { };
0148       }
0149     }
0150 }
0151 
0152 
0153 #endif