File indexing completed on 2025-01-31 10:02:38
0001
0002
0003
0004
0005
0006
0007
0008
0009 #if !defined(BOOST_SPIRIT_X3_MOVE_TO_JAN_17_2013_0859PM)
0010 #define BOOST_SPIRIT_X3_MOVE_TO_JAN_17_2013_0859PM
0011
0012 #include <boost/spirit/home/x3/support/traits/attribute_category.hpp>
0013 #include <boost/spirit/home/x3/support/traits/tuple_traits.hpp>
0014 #include <boost/spirit/home/x3/support/traits/variant_has_substitute.hpp>
0015
0016 #include <boost/assert.hpp>
0017 #include <boost/fusion/include/is_sequence.hpp>
0018 #include <boost/fusion/include/front.hpp>
0019 #include <boost/fusion/include/move.hpp>
0020 #include <boost/fusion/include/is_sequence.hpp>
0021 #include <utility>
0022
0023 namespace boost { namespace spirit { namespace x3 { namespace traits
0024 {
0025 template <typename Source, typename Dest>
0026 inline void move_to(Source&& src, Dest& dest);
0027
0028 template <typename T>
0029 inline void move_to(T& src, T& dest);
0030
0031 template <typename T>
0032 inline void move_to(T const& src, T& dest);
0033
0034 template <typename T>
0035 inline void move_to(T&& src, T& dest);
0036
0037 template <typename Iterator, typename Dest>
0038 inline void move_to(Iterator first, Iterator last, Dest& dest);
0039
0040 template <typename Dest>
0041 inline void move_to(unused_type, Dest&) {}
0042
0043 template <typename Source>
0044 inline void move_to(Source&, unused_type) {}
0045
0046 inline void move_to(unused_type, unused_type) {}
0047
0048 template <typename Iterator>
0049 inline void
0050 move_to(Iterator, Iterator, unused_type) {}
0051
0052 namespace detail
0053 {
0054 template <typename Source, typename Dest>
0055 inline void
0056 move_to(Source&, Dest&, unused_attribute) {}
0057
0058 template <typename Source, typename Dest>
0059 inline void
0060 move_to_plain(Source& src, Dest& dest, mpl::false_)
0061 {
0062 dest = std::move(src);
0063 }
0064
0065 template <typename Source, typename Dest>
0066 inline void
0067 move_to_plain(Source& src, Dest& dest, mpl::true_)
0068 {
0069 dest = std::move(fusion::front(src));
0070 }
0071
0072 template <typename Source, typename Dest>
0073 inline void
0074 move_to(Source& src, Dest& dest, plain_attribute)
0075 {
0076 typename mpl::and_<
0077 fusion::traits::is_sequence<Source>,
0078 is_size_one_sequence<Source> >
0079 is_single_element_sequence;
0080
0081 move_to_plain(src, dest, is_single_element_sequence);
0082 }
0083
0084 template <typename Source, typename Dest>
0085 inline typename enable_if<is_container<Source>>::type
0086 move_to(Source& src, Dest& dest, container_attribute)
0087 {
0088 traits::move_to(src.begin(), src.end(), dest);
0089 }
0090
0091 template <typename Source, typename Dest>
0092 inline typename enable_if<
0093 mpl::and_<
0094 is_same_size_sequence<Dest, Source>,
0095 mpl::not_<is_size_one_sequence<Dest> > >
0096 >::type
0097 move_to(Source& src, Dest& dest, tuple_attribute)
0098 {
0099 fusion::move(std::move(src), dest);
0100 }
0101
0102 template <typename Source, typename Dest>
0103 inline typename enable_if<
0104 is_size_one_sequence<Dest>
0105 >::type
0106 move_to(Source& src, Dest& dest, tuple_attribute)
0107 {
0108 traits::move_to(src, fusion::front(dest));
0109 }
0110
0111 template <typename Source, typename Dest>
0112 inline void
0113 move_to(Source& src, Dest& dest, variant_attribute, mpl::false_)
0114 {
0115 dest = std::move(src);
0116 }
0117
0118 template <typename Source, typename Dest>
0119 inline void
0120 move_to_variant_from_single_element_sequence(Source& src, Dest& dest, mpl::false_)
0121 {
0122
0123
0124
0125
0126 static_assert(variant_has_substitute<Dest, typename fusion::result_of::front<Source>::type>::value,
0127 "Error! The destination variant (Dest) cannot hold the source type (Source)");
0128
0129 dest = std::move(fusion::front(src));
0130 }
0131
0132 template <typename Source, typename Dest>
0133 inline void
0134 move_to_variant_from_single_element_sequence(Source& src, Dest& dest, mpl::true_)
0135 {
0136
0137
0138 dest = std::move(src);
0139 }
0140
0141 template <typename Source, typename Dest>
0142 inline void
0143 move_to(Source& src, Dest& dest, variant_attribute, mpl::true_)
0144 {
0145 move_to_variant_from_single_element_sequence(src, dest, variant_has_substitute<Dest, Source>());
0146 }
0147
0148 template <typename Source, typename Dest>
0149 inline void
0150 move_to(Source& src, Dest& dest, variant_attribute tag)
0151 {
0152 move_to(src, dest, tag, is_size_one_sequence<Source>());
0153 }
0154
0155 template <typename Source, typename Dest>
0156 inline void
0157 move_to(Source& src, Dest& dest, optional_attribute)
0158 {
0159 dest = std::move(src);
0160 }
0161
0162 template <typename Iterator>
0163 inline void
0164 move_to(Iterator, Iterator, unused_type, unused_attribute) {}
0165
0166 template <typename Iterator, typename Dest>
0167 inline void
0168 move_to(Iterator first, Iterator last, Dest& dest, container_attribute)
0169 {
0170 if (is_empty(dest))
0171 dest = Dest(first, last);
0172 else
0173 append(dest, first, last);
0174 }
0175
0176 template <typename Iterator, typename Dest>
0177 inline typename enable_if<
0178 is_size_one_sequence<Dest>
0179 >::type
0180 move_to(Iterator first, Iterator last, Dest& dest, tuple_attribute)
0181 {
0182 traits::move_to(first, last, fusion::front(dest));
0183 }
0184
0185 template <typename Iterator>
0186 inline void
0187 move_to(Iterator first, Iterator last, boost::iterator_range<Iterator>& rng, range_attribute)
0188 {
0189 rng = {first, last};
0190 }
0191 }
0192
0193 template <typename Source, typename Dest>
0194 inline void move_to(Source&& src, Dest& dest)
0195 {
0196 detail::move_to(src, dest, typename attribute_category<Dest>::type());
0197 }
0198
0199 template <typename T>
0200 inline void move_to(T& src, T& dest)
0201 {
0202 BOOST_ASSERT(boost::addressof(src) != boost::addressof(dest));
0203 dest = std::move(src);
0204 }
0205
0206 template <typename T>
0207 inline void move_to(T const& src, T& dest)
0208 {
0209 BOOST_ASSERT(boost::addressof(src) != boost::addressof(dest));
0210 dest = src;
0211 }
0212
0213 template <typename T>
0214 inline void move_to(T&& src, T& dest)
0215 {
0216 BOOST_ASSERT(boost::addressof(src) != boost::addressof(dest));
0217 dest = std::move(src);
0218 }
0219
0220 template <typename Iterator, typename Dest>
0221 inline void move_to(Iterator first, Iterator last, Dest& dest)
0222 {
0223
0224 detail::move_to(first, last, dest, typename attribute_category<Dest>::type());
0225 }
0226 }}}}
0227
0228 #endif