source: NonGTP/Boost/boost/python/detail/def_helper.hpp @ 857

Revision 857, 6.6 KB checked in by igarcia, 19 years ago (diff)
RevLine 
[857]1// Copyright David Abrahams 2002.
2// Distributed under the Boost Software License, Version 1.0. (See
3// accompanying file LICENSE_1_0.txt or copy at
4// http://www.boost.org/LICENSE_1_0.txt)
5#ifndef DEF_HELPER_DWA200287_HPP
6# define DEF_HELPER_DWA200287_HPP
7
8# include <boost/python/args.hpp>
9# include <boost/type_traits/ice.hpp>
10# include <boost/type_traits/same_traits.hpp>
11# include <boost/python/detail/indirect_traits.hpp>
12# include <boost/mpl/not.hpp>
13# include <boost/mpl/and.hpp>
14# include <boost/mpl/or.hpp>
15# include <boost/type_traits/add_reference.hpp>
16# include <boost/mpl/lambda.hpp>
17# include <boost/mpl/apply.hpp>
18# include <boost/tuple/tuple.hpp>
19# include <boost/python/detail/not_specified.hpp>
20# include <boost/python/detail/def_helper_fwd.hpp>
21
22namespace boost { namespace python {
23
24struct default_call_policies;
25
26namespace detail
27{
28  // tuple_extract<Tuple,Predicate>::extract(t) returns the first
29  // element of a Tuple whose type E satisfies the given Predicate
30  // applied to add_reference<E>. The Predicate must be an MPL
31  // metafunction class.
32  template <class Tuple, class Predicate>
33  struct tuple_extract;
34
35  // Implementation class for when the tuple's head type does not
36  // satisfy the Predicate
37  template <bool matched>
38  struct tuple_extract_impl
39  {
40      template <class Tuple, class Predicate>
41      struct apply
42      {
43          typedef typename Tuple::head_type result_type;
44         
45          static typename Tuple::head_type extract(Tuple const& x)
46          {
47              return x.get_head();
48          }
49      };
50  };
51
52  // Implementation specialization for when the tuple's head type
53  // satisfies the predicate
54  template <>
55  struct tuple_extract_impl<false>
56  {
57      template <class Tuple, class Predicate>
58      struct apply
59      {
60          // recursive application of tuple_extract on the tail of the tuple
61          typedef tuple_extract<typename Tuple::tail_type, Predicate> next;
62          typedef typename next::result_type result_type;
63         
64          static result_type extract(Tuple const& x)
65          {
66              return next::extract(x.get_tail());
67          }
68      };
69  };
70
71  // A metafunction which selects a version of tuple_extract_impl to
72  // use for the implementation of tuple_extract
73  template <class Tuple, class Predicate>
74  struct tuple_extract_base_select
75  {
76      typedef typename Tuple::head_type head_type;
77      typedef typename mpl::apply1<Predicate, typename add_reference<head_type>::type>::type match_t;
78      BOOST_STATIC_CONSTANT(bool, match = match_t::value);
79      typedef typename tuple_extract_impl<match>::template apply<Tuple,Predicate> type;
80  };
81 
82  template <class Tuple, class Predicate>
83  struct tuple_extract
84      : tuple_extract_base_select<
85         Tuple
86         , typename mpl::lambda<Predicate>::type
87      >::type
88  {
89  };
90
91
92  //
93  // Specialized extractors for the docstring, keywords, CallPolicies,
94  // and default implementation of virtual functions
95  //
96
97  template <class Tuple>
98  struct doc_extract
99      : tuple_extract<
100        Tuple
101        , mpl::not_<
102           mpl::or_<
103               indirect_traits::is_reference_to_class<mpl::_1>
104             , indirect_traits::is_reference_to_member_function_pointer<mpl::_1 >
105           >
106        >
107     >
108  {
109  };
110 
111  template <class Tuple>
112  struct keyword_extract
113      : tuple_extract<Tuple, is_reference_to_keywords<mpl::_1 > >
114  {
115  };
116
117  template <class Tuple>
118  struct policy_extract
119      : tuple_extract<
120          Tuple
121          , mpl::and_<
122             mpl::not_<is_same<not_specified const&,mpl::_1> >
123              , indirect_traits::is_reference_to_class<mpl::_1 >
124              , mpl::not_<is_reference_to_keywords<mpl::_1 > >
125          >
126        >
127  {
128  };
129
130  template <class Tuple>
131  struct default_implementation_extract
132      : tuple_extract<
133          Tuple
134          , indirect_traits::is_reference_to_member_function_pointer<mpl::_1 >
135          >
136  {
137  };
138
139  //
140  // A helper class for decoding the optional arguments to def()
141  // invocations, which can be supplied in any order and are
142  // discriminated by their type properties. The template parameters
143  // are expected to be the types of the actual (optional) arguments
144  // passed to def().
145  //
146  template <class T1, class T2, class T3, class T4>
147  struct def_helper
148  {
149      // A tuple type which begins with references to the supplied
150      // arguments and ends with actual representatives of the default
151      // types.
152      typedef boost::tuples::tuple<
153          T1 const&
154          , T2 const&
155          , T3 const&
156          , T4 const&
157          , default_call_policies
158          , keywords<0>
159          , char const*
160          , void(not_specified::*)()   // A function pointer type which is never an
161                                       // appropriate default implementation
162          > all_t;
163
164      // Constructors; these initialize an member of the tuple type
165      // shown above.
166      def_helper(T1 const& a1) : m_all(a1,m_nil,m_nil,m_nil) {}
167      def_helper(T1 const& a1, T2 const& a2) : m_all(a1,a2,m_nil,m_nil) {}
168      def_helper(T1 const& a1, T2 const& a2, T3 const& a3) : m_all(a1,a2,a3,m_nil) {}
169      def_helper(T1 const& a1, T2 const& a2, T3 const& a3, T4 const& a4) : m_all(a1,a2,a3,a4) {}
170
171   private: // types
172      typedef typename default_implementation_extract<all_t>::result_type default_implementation_t;
173     
174   public: // Constants which can be used for static assertions.
175
176      // Users must not supply a default implementation for non-class
177      // methods.
178      BOOST_STATIC_CONSTANT(
179          bool, has_default_implementation = (
180              !is_same<default_implementation_t, void(not_specified::*)()>::value));
181     
182   public: // Extractor functions which pull the appropriate value out
183           // of the tuple
184      char const* doc() const
185      {
186          return doc_extract<all_t>::extract(m_all);
187      }
188     
189      typename keyword_extract<all_t>::result_type keywords() const
190      {
191          return keyword_extract<all_t>::extract(m_all);
192      }
193     
194      typename policy_extract<all_t>::result_type policies() const
195      {
196          return policy_extract<all_t>::extract(m_all);
197      }
198
199      default_implementation_t default_implementation() const
200      {
201          return default_implementation_extract<all_t>::extract(m_all);
202      }
203     
204   private: // data members
205      all_t m_all;
206      not_specified m_nil; // for filling in not_specified slots
207  };
208}
209
210}} // namespace boost::python::detail
211
212#endif // DEF_HELPER_DWA200287_HPP
Note: See TracBrowser for help on using the repository browser.