123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228 |
- /*=============================================================================
- Copyright (c) 2001-2014 Joel de Guzman
- Copyright (c) 2013 Agustin Berge
- http://spirit.sourceforge.net/
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- =============================================================================*/
- #if !defined(BOOST_SPIRIT_X3_MOVE_TO_JAN_17_2013_0859PM)
- #define BOOST_SPIRIT_X3_MOVE_TO_JAN_17_2013_0859PM
- #include <boost/spirit/home/x3/support/traits/attribute_category.hpp>
- #include <boost/spirit/home/x3/support/traits/tuple_traits.hpp>
- #include <boost/spirit/home/x3/support/traits/variant_has_substitute.hpp>
- #include <boost/assert.hpp>
- #include <boost/fusion/include/is_sequence.hpp>
- #include <boost/fusion/include/front.hpp>
- #include <boost/fusion/include/move.hpp>
- #include <boost/fusion/include/is_sequence.hpp>
- #include <utility>
- namespace boost { namespace spirit { namespace x3 { namespace traits
- {
- template <typename Source, typename Dest>
- inline void move_to(Source&& src, Dest& dest);
- template <typename T>
- inline void move_to(T& src, T& dest);
- template <typename T>
- inline void move_to(T const& src, T& dest);
- template <typename T>
- inline void move_to(T&& src, T& dest);
- template <typename Iterator, typename Dest>
- inline void move_to(Iterator first, Iterator last, Dest& dest);
- template <typename Dest>
- inline void move_to(unused_type, Dest&) {}
- template <typename Source>
- inline void move_to(Source&, unused_type) {}
- inline void move_to(unused_type, unused_type) {}
- template <typename Iterator>
- inline void
- move_to(Iterator, Iterator, unused_type) {}
- namespace detail
- {
- template <typename Source, typename Dest>
- inline void
- move_to(Source&, Dest&, unused_attribute) {}
-
- template <typename Source, typename Dest>
- inline void
- move_to_plain(Source& src, Dest& dest, mpl::false_) // src is not a single-element tuple
- {
- dest = std::move(src);
- }
-
- template <typename Source, typename Dest>
- inline void
- move_to_plain(Source& src, Dest& dest, mpl::true_) // src is a single-element tuple
- {
- dest = std::move(fusion::front(src));
- }
- template <typename Source, typename Dest>
- inline void
- move_to(Source& src, Dest& dest, plain_attribute)
- {
- typename mpl::and_<
- fusion::traits::is_sequence<Source>,
- is_size_one_sequence<Source> >
- is_single_element_sequence;
-
- move_to_plain(src, dest, is_single_element_sequence);
- }
- template <typename Source, typename Dest>
- inline typename enable_if<is_container<Source>>::type
- move_to(Source& src, Dest& dest, container_attribute)
- {
- traits::move_to(src.begin(), src.end(), dest);
- }
- template <typename Source, typename Dest>
- inline typename enable_if<
- mpl::and_<
- is_same_size_sequence<Dest, Source>,
- mpl::not_<is_size_one_sequence<Dest> > >
- >::type
- move_to(Source& src, Dest& dest, tuple_attribute)
- {
- fusion::move(std::move(src), dest);
- }
- template <typename Source, typename Dest>
- inline typename enable_if<
- is_size_one_sequence<Dest>
- >::type
- move_to(Source& src, Dest& dest, tuple_attribute)
- {
- traits::move_to(src, fusion::front(dest));
- }
- template <typename Source, typename Dest>
- inline void
- move_to(Source& src, Dest& dest, variant_attribute, mpl::false_)
- {
- dest = std::move(src);
- }
-
- template <typename Source, typename Dest>
- inline void
- move_to_variant_from_single_element_sequence(Source& src, Dest& dest, mpl::false_)
- {
- // dest is a variant, src is a single element fusion sequence that the variant
- // cannot directly hold. We'll try to unwrap the single element fusion sequence.
-
- // Make sure that the Dest variant can really hold Source
- static_assert(variant_has_substitute<Dest, typename fusion::result_of::front<Source>::type>::value,
- "Error! The destination variant (Dest) cannot hold the source type (Source)");
-
- dest = std::move(fusion::front(src));
- }
-
- template <typename Source, typename Dest>
- inline void
- move_to_variant_from_single_element_sequence(Source& src, Dest& dest, mpl::true_)
- {
- // dest is a variant, src is a single element fusion sequence that the variant
- // *can* directly hold.
- dest = std::move(src);
- }
- template <typename Source, typename Dest>
- inline void
- move_to(Source& src, Dest& dest, variant_attribute, mpl::true_)
- {
- move_to_variant_from_single_element_sequence(src, dest, variant_has_substitute<Dest, Source>());
- }
- template <typename Source, typename Dest>
- inline void
- move_to(Source& src, Dest& dest, variant_attribute tag)
- {
- move_to(src, dest, tag, is_size_one_sequence<Source>());
- }
- template <typename Source, typename Dest>
- inline void
- move_to(Source& src, Dest& dest, optional_attribute)
- {
- dest = std::move(src);
- }
- template <typename Iterator>
- inline void
- move_to(Iterator, Iterator, unused_type, unused_attribute) {}
- template <typename Iterator, typename Dest>
- inline void
- move_to(Iterator first, Iterator last, Dest& dest, container_attribute)
- {
- if (is_empty(dest))
- dest = Dest(first, last);
- else
- append(dest, first, last);
- }
- template <typename Iterator, typename Dest>
- inline typename enable_if<
- is_size_one_sequence<Dest>
- >::type
- move_to(Iterator first, Iterator last, Dest& dest, tuple_attribute)
- {
- traits::move_to(first, last, fusion::front(dest));
- }
-
- template <typename Iterator>
- inline void
- move_to(Iterator first, Iterator last, boost::iterator_range<Iterator>& rng, range_attribute)
- {
- rng = {first, last};
- }
- }
- template <typename Source, typename Dest>
- inline void move_to(Source&& src, Dest& dest)
- {
- detail::move_to(src, dest, typename attribute_category<Dest>::type());
- }
- template <typename T>
- inline void move_to(T& src, T& dest)
- {
- BOOST_ASSERT(boost::addressof(src) != boost::addressof(dest));
- dest = std::move(src);
- }
- template <typename T>
- inline void move_to(T const& src, T& dest)
- {
- BOOST_ASSERT(boost::addressof(src) != boost::addressof(dest));
- dest = src;
- }
- template <typename T>
- inline void move_to(T&& src, T& dest)
- {
- BOOST_ASSERT(boost::addressof(src) != boost::addressof(dest));
- dest = std::move(src);
- }
- template <typename Iterator, typename Dest>
- inline void move_to(Iterator first, Iterator last, Dest& dest)
- {
- // $$$ Use std::move_iterator when iterator is not a const-iterator $$$
- detail::move_to(first, last, dest, typename attribute_category<Dest>::type());
- }
- }}}}
- #endif
|