summaryrefslogtreecommitdiff
path: root/boost/phoenix/function/lazy_smart.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/phoenix/function/lazy_smart.hpp')
-rw-r--r--boost/phoenix/function/lazy_smart.hpp153
1 files changed, 153 insertions, 0 deletions
diff --git a/boost/phoenix/function/lazy_smart.hpp b/boost/phoenix/function/lazy_smart.hpp
new file mode 100644
index 0000000000..17e142997f
--- /dev/null
+++ b/boost/phoenix/function/lazy_smart.hpp
@@ -0,0 +1,153 @@
+////////////////////////////////////////////////////////////////////////////
+// lazy smart.hpp
+//
+// Build lazy functoid traits for Phoenix equivalents for FC++
+//
+// These are equivalents of the Boost FC++ functoid traits in smart.hpp
+//
+// I have copied the versions for zero, one, two and three arguments.
+//
+/*=============================================================================
+ Copyright (c) 2000-2003 Brian McNamara and Yannis Smaragdakis
+ Copyright (c) 2001-2007 Joel de Guzman
+ Copyright (c) 2015 John Fletcher
+
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_PHOENIX_FUNCTION_LAZY_SMART
+#define BOOST_PHOENIX_FUNCTION_LAZY_SMART
+
+namespace boost {
+ namespace phoenix {
+ namespace fcpp {
+
+//////////////////////////////////////////////////////////////////////
+// Feature: Smartness
+//////////////////////////////////////////////////////////////////////
+// If F is smart, then we can refer to these entities:
+//
+// functoid_traits<F>::template accepts<N>::args
+// A bool which says whether F can accept N arguments
+//
+// functoid_traits<F>::max_args
+// An int which says what the most arguments F can accept is
+//
+// functoid_traits<F>::template ensure_accepts<N>::args()
+// A no-op call that compiles only if F can accept N args
+//
+// We use traits so that if you happen to ask a non-smart functoid these
+// questions, you will hopefully get a literate error message.
+
+struct SmartFunctoid {};
+
+// We add crazy identifiers to ensure that users don't accidentally talk
+// to functoids directly; they should always be going through the traits
+// class to ask for info.
+struct smart_functoid0 : public SmartFunctoid {
+ template <class Dummy, int i> struct crazy_accepts {
+ static const bool args = false;
+ };
+ template <class Dummy> struct crazy_accepts<Dummy,0> {
+ static const bool args = true;
+ };
+ static const int crazy_max_args = 0;
+};
+
+struct smart_functoid1 : public SmartFunctoid {
+ template <class Dummy, int i> struct crazy_accepts {
+ static const bool args = false;
+ };
+ template <class Dummy> struct crazy_accepts<Dummy,1> {
+ static const bool args = true;
+ };
+ static const int crazy_max_args = 1;
+};
+
+struct smart_functoid2 : public SmartFunctoid {
+ template <class Dummy, int i> struct crazy_accepts {
+ static const bool args = false;
+ };
+ template <class Dummy> struct crazy_accepts<Dummy,1> {
+ static const bool args = true;
+ };
+ template <class Dummy> struct crazy_accepts<Dummy,2> {
+ static const bool args = true;
+ };
+ static const int crazy_max_args = 2;
+};
+
+struct smart_functoid3 : public SmartFunctoid {
+ template <class Dummy, int i> struct crazy_accepts {
+ static const bool args = false;
+ };
+ template <class Dummy> struct crazy_accepts<Dummy,1> {
+ static const bool args = true;
+ };
+ template <class Dummy> struct crazy_accepts<Dummy,2> {
+ static const bool args = true;
+ };
+ template <class Dummy> struct crazy_accepts<Dummy,3> {
+ static const bool args = true;
+ };
+ static const int crazy_max_args = 3;
+};
+
+
+namespace impl {
+ template <class F, bool b> struct NeededASmartFunctoidButInsteadGot {};
+ template <class F> struct NeededASmartFunctoidButInsteadGot<F,true> {
+ typedef F type;
+ };
+ template <bool b> struct Ensure;
+ template <> struct Ensure<true> {};
+} // end namespace impl
+
+template <class MaybeASmartFunctoid>
+struct functoid_traits {
+ typedef typename boost::remove_reference<MaybeASmartFunctoid>::type MaybeASmartFunctoidT;
+ typedef
+ typename impl::NeededASmartFunctoidButInsteadGot<MaybeASmartFunctoidT,
+ boost::is_base_and_derived<SmartFunctoid,
+ MaybeASmartFunctoidT>::value>::type F;
+ template <int i> struct accepts {
+ static const bool args = F::template crazy_accepts<int,i>::args;
+ };
+ template <int i> struct ensure_accepts {
+ static const bool ok = F::template crazy_accepts<int,i>::args;
+ inline static void args() { (void) impl::Ensure<ok>(); }
+ };
+ static const int max_args = F::crazy_max_args;
+};
+
+// These can be used to make functoids smart without having to alter
+// code elsewhere. These are used instead of boost::phoenix::function
+// to declare the object.
+template <typename F>
+struct smart_function0 : public smart_functoid0,
+ public boost::phoenix::function<F>
+{ };
+
+template <typename F>
+struct smart_function1 : public smart_functoid1,
+ public boost::phoenix::function<F>
+{
+ typedef F type;
+};
+
+template <typename F>
+struct smart_function2 : public smart_functoid2,
+ public boost::phoenix::function<F>
+{ };
+
+template <typename F>
+struct smart_function3 : public smart_functoid3,
+ public boost::phoenix::function<F>
+{ };
+ }
+ }
+}
+
+
+#endif