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