]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/spirit/home/x3/support/traits/move_to.hpp
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / boost / boost / spirit / home / x3 / support / traits / move_to.hpp
1 /*=============================================================================
2 Copyright (c) 2001-2014 Joel de Guzman
3 Copyright (c) 2013 Agustin Berge
4 http://spirit.sourceforge.net/
5
6 Distributed under the Boost Software License, Version 1.0. (See accompanying
7 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 =============================================================================*/
9 #if !defined(BOOST_SPIRIT_X3_MOVE_TO_JAN_17_2013_0859PM)
10 #define BOOST_SPIRIT_X3_MOVE_TO_JAN_17_2013_0859PM
11
12 #include <boost/spirit/home/x3/support/traits/attribute_category.hpp>
13 #include <boost/spirit/home/x3/support/traits/tuple_traits.hpp>
14 #include <boost/spirit/home/x3/support/traits/variant_has_substitute.hpp>
15 #include <boost/fusion/include/is_sequence.hpp>
16 #include <boost/fusion/include/front.hpp>
17 #include <boost/fusion/include/size.hpp>
18 #include <boost/fusion/include/move.hpp>
19 #include <boost/fusion/include/is_sequence.hpp>
20 #include <utility>
21
22 namespace boost { namespace spirit { namespace x3 { namespace traits
23 {
24 template <typename Source, typename Dest>
25 inline void move_to(Source&& src, Dest& dest);
26
27 template <typename T>
28 inline void move_to(T& src, T& dest);
29
30 template <typename T>
31 inline void move_to(T const& src, T& dest);
32
33 template <typename T>
34 inline void move_to(T&& src, T& dest);
35
36 template <typename Iterator, typename Dest>
37 inline void move_to(Iterator first, Iterator last, Dest& dest);
38
39 template <typename Dest>
40 inline void move_to(unused_type, Dest&) {}
41
42 template <typename Source>
43 inline void move_to(Source&, unused_type) {}
44
45 inline void move_to(unused_type, unused_type) {}
46
47 template <typename Iterator>
48 inline void
49 move_to(Iterator, Iterator, unused_type) {}
50
51 namespace detail
52 {
53 template <typename Source, typename Dest>
54 inline void
55 move_to(Source&&, Dest&, unused_attribute) {}
56
57 template <typename Source, typename Dest>
58 inline void
59 move_to_plain(Source&& src, Dest& dest, mpl::false_) // src is not a single-element tuple
60 {
61 dest = std::move(src);
62 }
63
64 template <typename Source, typename Dest>
65 inline void
66 move_to_plain(Source&& src, Dest& dest, mpl::true_) // src is a single-element tuple
67 {
68 dest = std::move(fusion::front(src));
69 }
70
71 template <typename Source, typename Dest>
72 inline void
73 move_to(Source&& src, Dest& dest, plain_attribute)
74 {
75 typename mpl::and_<
76 fusion::traits::is_sequence<Source>,
77 is_size_one_sequence<Source> >
78 is_single_element_sequence;
79
80 move_to_plain(std::forward<Source>(src), dest, is_single_element_sequence);
81 }
82
83 template <typename Source, typename Dest>
84 inline typename enable_if<is_container<Source>>::type
85 move_to(Source&& src, Dest& dest, container_attribute)
86 {
87 traits::move_to(src.begin(), src.end(), dest);
88 }
89
90 template <typename Source, typename Dest>
91 inline typename enable_if<
92 mpl::and_<
93 is_same_size_sequence<Dest, Source>,
94 mpl::not_<is_size_one_sequence<Dest> > >
95 >::type
96 move_to(Source&& src, Dest& dest, tuple_attribute)
97 {
98 fusion::move(std::forward<Source>(src), dest);
99 }
100
101 template <typename Source, typename Dest>
102 inline typename enable_if<
103 is_size_one_sequence<Dest>
104 >::type
105 move_to(Source&& src, Dest& dest, tuple_attribute)
106 {
107 traits::move_to(std::forward<Source>(src), fusion::front(dest));
108 }
109
110 template <typename Source, typename Dest>
111 inline void
112 move_to(Source&& src, Dest& dest, variant_attribute, mpl::false_)
113 {
114 dest = std::move(src);
115 }
116
117 template <typename Source, typename Dest>
118 inline void
119 move_to_variant_from_single_element_sequence(Source&& src, Dest& dest, mpl::false_)
120 {
121 // dest is a variant, src is a single element fusion sequence that the variant
122 // cannot directly hold. We'll try to unwrap the single element fusion sequence.
123
124 // Make sure that the Dest variant can really hold Source
125 static_assert(variant_has_substitute<Dest, typename fusion::result_of::front<Source>::type>::value,
126 "Error! The destination variant (Dest) cannot hold the source type (Source)");
127
128 dest = std::move(fusion::front(src));
129 }
130
131 template <typename Source, typename Dest>
132 inline void
133 move_to_variant_from_single_element_sequence(Source&& src, Dest& dest, mpl::true_)
134 {
135 // dest is a variant, src is a single element fusion sequence that the variant
136 // *can* directly hold.
137 dest = std::move(src);
138 }
139
140 template <typename Source, typename Dest>
141 inline void
142 move_to(Source&& src, Dest& dest, variant_attribute, mpl::true_)
143 {
144 move_to_variant_from_single_element_sequence(src, dest, variant_has_substitute<Dest, Source>());
145 }
146
147 template <typename Source, typename Dest>
148 inline void
149 move_to(Source&& src, Dest& dest, variant_attribute tag)
150 {
151 move_to(src, dest, tag, is_size_one_sequence<Source>());
152 }
153
154 template <typename Source, typename Dest>
155 inline void
156 move_to(Source&& src, Dest& dest, optional_attribute)
157 {
158 dest = std::move(src);
159 }
160
161 template <typename Iterator>
162 inline void
163 move_to(Iterator, Iterator, unused_type, unused_attribute) {}
164
165 template <typename Iterator, typename Dest>
166 inline void
167 move_to(Iterator first, Iterator last, Dest& dest, container_attribute)
168 {
169 if (is_empty(dest))
170 dest = Dest(first, last);
171 else
172 append(dest, first, last);
173 }
174
175 template <typename Iterator, typename Dest>
176 inline typename enable_if<
177 is_size_one_sequence<Dest>
178 >::type
179 move_to(Iterator first, Iterator last, Dest& dest, tuple_attribute)
180 {
181 traits::move_to(first, last, fusion::front(dest));
182 }
183
184 template <typename Iterator>
185 inline void
186 move_to(Iterator first, Iterator last, boost::iterator_range<Iterator>& rng, range_attribute)
187 {
188 rng = {first, last};
189 }
190 }
191
192 template <typename Source, typename Dest>
193 inline void move_to(Source&& src, Dest& dest)
194 {
195 detail::move_to(std::move(src), dest
196 , typename attribute_category<Dest>::type());
197 }
198
199 template <typename T>
200 inline void move_to(T& src, T& dest)
201 {
202 if (boost::addressof(src) != boost::addressof(dest))
203 dest = std::move(src);
204 }
205
206 template <typename T>
207 inline void move_to(T const& src, T& dest)
208 {
209 if (boost::addressof(src) != boost::addressof(dest))
210 dest = std::move(src);
211 }
212
213 template <typename T>
214 inline void move_to(T&& src, T& dest)
215 {
216 if (boost::addressof(src) != boost::addressof(dest))
217 dest = std::move(src);
218 }
219
220 template <typename Iterator, typename Dest>
221 inline void move_to(Iterator first, Iterator last, Dest& dest)
222 {
223 // $$$ Use std::move_iterator when iterator is not a const-iterator $$$
224 detail::move_to(first, last, dest, typename attribute_category<Dest>::type());
225 }
226 }}}}
227
228 #endif