Chris@16
|
1 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
2 /// \file deep_copy.hpp
|
Chris@16
|
3 /// Replace all nodes stored by reference by nodes stored by value.
|
Chris@16
|
4 //
|
Chris@16
|
5 // Copyright 2008 Eric Niebler. Distributed under the Boost
|
Chris@16
|
6 // Software License, Version 1.0. (See accompanying file
|
Chris@16
|
7 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
8
|
Chris@16
|
9 #ifndef BOOST_PROTO_DEEP_COPY_HPP_EAN_11_21_2006
|
Chris@16
|
10 #define BOOST_PROTO_DEEP_COPY_HPP_EAN_11_21_2006
|
Chris@16
|
11
|
Chris@16
|
12 #include <boost/preprocessor/cat.hpp>
|
Chris@16
|
13 #include <boost/preprocessor/repetition/enum.hpp>
|
Chris@16
|
14 #include <boost/preprocessor/iteration/iterate.hpp>
|
Chris@16
|
15 #include <boost/mpl/if.hpp>
|
Chris@16
|
16 #include <boost/type_traits/remove_reference.hpp>
|
Chris@16
|
17 #include <boost/proto/proto_fwd.hpp>
|
Chris@16
|
18 #include <boost/proto/args.hpp>
|
Chris@16
|
19 #include <boost/proto/expr.hpp>
|
Chris@16
|
20
|
Chris@16
|
21 namespace boost { namespace proto
|
Chris@16
|
22 {
|
Chris@16
|
23 namespace detail
|
Chris@16
|
24 {
|
Chris@16
|
25 template<typename Expr, long Arity = Expr::proto_arity_c>
|
Chris@16
|
26 struct deep_copy_impl;
|
Chris@16
|
27
|
Chris@16
|
28 template<typename Expr>
|
Chris@16
|
29 struct deep_copy_impl<Expr, 0>
|
Chris@16
|
30 {
|
Chris@16
|
31 typedef
|
Chris@16
|
32 typename base_expr<
|
Chris@16
|
33 typename Expr::proto_domain
|
Chris@16
|
34 , tag::terminal
|
Chris@16
|
35 , term<typename term_traits<typename Expr::proto_child0>::value_type>
|
Chris@16
|
36 >::type
|
Chris@16
|
37 expr_type;
|
Chris@16
|
38
|
Chris@16
|
39 typedef typename Expr::proto_generator proto_generator;
|
Chris@16
|
40 typedef typename proto_generator::template result<proto_generator(expr_type)>::type result_type;
|
Chris@16
|
41
|
Chris@16
|
42 template<typename Expr2, typename S, typename D>
|
Chris@16
|
43 result_type operator()(Expr2 const &e, S const &, D const &) const
|
Chris@16
|
44 {
|
Chris@16
|
45 return proto_generator()(expr_type::make(e.proto_base().child0));
|
Chris@16
|
46 }
|
Chris@16
|
47 };
|
Chris@16
|
48 }
|
Chris@16
|
49
|
Chris@16
|
50 namespace result_of
|
Chris@16
|
51 {
|
Chris@16
|
52 /// \brief A metafunction for calculating the return type
|
Chris@16
|
53 /// of \c proto::deep_copy().
|
Chris@16
|
54 ///
|
Chris@16
|
55 /// A metafunction for calculating the return type
|
Chris@16
|
56 /// of \c proto::deep_copy(). The type parameter \c Expr
|
Chris@16
|
57 /// should be the type of a Proto expression tree.
|
Chris@16
|
58 /// It should not be a reference type, nor should it
|
Chris@16
|
59 /// be cv-qualified.
|
Chris@16
|
60 template<typename Expr>
|
Chris@16
|
61 struct deep_copy
|
Chris@16
|
62 {
|
Chris@16
|
63 typedef
|
Chris@16
|
64 typename detail::deep_copy_impl<
|
Chris@16
|
65 BOOST_PROTO_UNCVREF(Expr)
|
Chris@16
|
66 >::result_type
|
Chris@16
|
67 type;
|
Chris@16
|
68 };
|
Chris@16
|
69 }
|
Chris@16
|
70
|
Chris@16
|
71 namespace functional
|
Chris@16
|
72 {
|
Chris@16
|
73 /// \brief A PolymorphicFunctionObject type for deep-copying
|
Chris@16
|
74 /// Proto expression trees.
|
Chris@16
|
75 ///
|
Chris@16
|
76 /// A PolymorphicFunctionObject type for deep-copying
|
Chris@16
|
77 /// Proto expression trees. When a tree is deep-copied,
|
Chris@16
|
78 /// all internal nodes and most terminals held by reference
|
Chris@16
|
79 /// are instead held by value.
|
Chris@16
|
80 ///
|
Chris@16
|
81 /// \attention Terminals of reference-to-function type are
|
Chris@16
|
82 /// left unchanged. Terminals of reference-to-array type are
|
Chris@16
|
83 /// stored by value, which can cause a large amount of data
|
Chris@16
|
84 /// to be passed by value and stored on the stack.
|
Chris@16
|
85 struct deep_copy
|
Chris@16
|
86 {
|
Chris@16
|
87 BOOST_PROTO_CALLABLE()
|
Chris@16
|
88
|
Chris@16
|
89 template<typename Sig>
|
Chris@16
|
90 struct result;
|
Chris@16
|
91
|
Chris@16
|
92 template<typename This, typename Expr>
|
Chris@16
|
93 struct result<This(Expr)>
|
Chris@16
|
94 {
|
Chris@16
|
95 typedef
|
Chris@16
|
96 typename detail::deep_copy_impl<
|
Chris@16
|
97 BOOST_PROTO_UNCVREF(Expr)
|
Chris@16
|
98 >::result_type
|
Chris@16
|
99 type;
|
Chris@16
|
100 };
|
Chris@16
|
101
|
Chris@16
|
102 /// \brief Deep-copies a Proto expression tree, turning all
|
Chris@16
|
103 /// nodes and terminals held by reference into ones held by
|
Chris@16
|
104 /// value.
|
Chris@16
|
105 template<typename Expr>
|
Chris@16
|
106 typename result_of::deep_copy<Expr>::type
|
Chris@16
|
107 operator()(Expr const &e) const
|
Chris@16
|
108 {
|
Chris@16
|
109 return proto::detail::deep_copy_impl<Expr>()(e, 0, 0);
|
Chris@16
|
110 }
|
Chris@16
|
111 };
|
Chris@16
|
112 }
|
Chris@16
|
113
|
Chris@16
|
114 /// \brief A function for deep-copying
|
Chris@16
|
115 /// Proto expression trees.
|
Chris@16
|
116 ///
|
Chris@16
|
117 /// A function for deep-copying
|
Chris@16
|
118 /// Proto expression trees. When a tree is deep-copied,
|
Chris@16
|
119 /// all internal nodes and most terminals held by reference
|
Chris@16
|
120 /// are instead held by value.
|
Chris@16
|
121 ///
|
Chris@16
|
122 /// \attention Terminals of reference-to-function type are
|
Chris@16
|
123 /// left unchanged.
|
Chris@16
|
124 ///
|
Chris@16
|
125 /// \sa proto::functional::deep_copy.
|
Chris@16
|
126 template<typename Expr>
|
Chris@16
|
127 typename proto::result_of::deep_copy<Expr>::type
|
Chris@16
|
128 deep_copy(Expr const &e)
|
Chris@16
|
129 {
|
Chris@16
|
130 return proto::detail::deep_copy_impl<Expr>()(e, 0, 0);
|
Chris@16
|
131 }
|
Chris@16
|
132
|
Chris@16
|
133 /// \brief A PrimitiveTransform for deep-copying
|
Chris@16
|
134 /// Proto expression trees.
|
Chris@16
|
135 ///
|
Chris@16
|
136 /// A PrimitiveTransform for deep-copying
|
Chris@16
|
137 /// Proto expression trees. When a tree is deep-copied,
|
Chris@16
|
138 /// all internal nodes and most terminals held by reference
|
Chris@16
|
139 /// are instead held by value.
|
Chris@16
|
140 ///
|
Chris@16
|
141 /// \attention Terminals of reference-to-function type are
|
Chris@16
|
142 /// left unchanged.
|
Chris@16
|
143 ///
|
Chris@16
|
144 /// \sa proto::functional::deep_copy.
|
Chris@16
|
145 struct _deep_copy
|
Chris@16
|
146 : proto::transform<_deep_copy>
|
Chris@16
|
147 {
|
Chris@16
|
148 template<typename E, typename S, typename D>
|
Chris@16
|
149 struct impl
|
Chris@16
|
150 : detail::deep_copy_impl<BOOST_PROTO_UNCVREF(E)>
|
Chris@16
|
151 {};
|
Chris@16
|
152 };
|
Chris@16
|
153
|
Chris@16
|
154 namespace detail
|
Chris@16
|
155 {
|
Chris@16
|
156 // include the definition of deep_copy_impl
|
Chris@16
|
157 #include <boost/proto/detail/deep_copy.hpp>
|
Chris@16
|
158 }
|
Chris@16
|
159
|
Chris@16
|
160 }}
|
Chris@16
|
161
|
Chris@16
|
162 #endif // BOOST_PROTO_COMPILER_DEEP_COPY_HPP_EAN_11_21_2006
|
Chris@16
|
163
|