/*============================================================================= 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 #include #include #include #include #include #include #include namespace boost { namespace spirit { namespace x3 { namespace traits { template inline void move_to(Source&& src, Dest& dest); template inline void move_to(T& src, T& dest); template inline void move_to(T const& src, T& dest); template inline void move_to(T&& src, T& dest); template inline void move_to(Iterator first, Iterator last, Dest& dest); template inline void move_to(unused_type, Dest&) {} template inline void move_to(Source&, unused_type) {} inline void move_to(unused_type, unused_type) {} template inline void move_to(Iterator, Iterator, unused_type) {} namespace detail { template inline void move_to(Source&&, Dest&, unused_attribute) {} template inline void move_to_plain(Source&& src, Dest& dest, mpl::false_) // src is not a single-element tuple { dest = std::move(src); } template inline void move_to_plain(Source&& src, Dest& dest, mpl::true_) // src is a single-element tuple { dest = std::move(fusion::front(src)); } template inline void move_to(Source&& src, Dest& dest, plain_attribute) { typename mpl::and_< fusion::traits::is_sequence, is_size_one_sequence > is_single_element_sequence; move_to_plain(std::forward(src), dest, is_single_element_sequence); } template inline typename enable_if>::type move_to(Source&& src, Dest& dest, container_attribute) { traits::move_to(src.begin(), src.end(), dest); } template inline typename enable_if< mpl::and_< is_same_size_sequence, mpl::not_ > > >::type move_to(Source&& src, Dest& dest, tuple_attribute) { fusion::move(std::forward(src), dest); } template inline typename enable_if< is_size_one_sequence >::type move_to(Source&& src, Dest& dest, tuple_attribute) { traits::move_to(std::forward(src), fusion::front(dest)); } template inline void move_to(Source&& src, Dest& dest, variant_attribute, mpl::false_) { dest = std::move(src); } template 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::type>::value, "Error! The destination variant (Dest) cannot hold the source type (Source)"); dest = std::move(fusion::front(src)); } template 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 inline void move_to(Source&& src, Dest& dest, variant_attribute, mpl::true_) { move_to_variant_from_single_element_sequence(src, dest, variant_has_substitute()); } template inline void move_to(Source&& src, Dest& dest, variant_attribute tag) { move_to(src, dest, tag, is_size_one_sequence()); } template inline void move_to(Source&& src, Dest& dest, optional_attribute) { dest = std::move(src); } template inline void move_to(Iterator, Iterator, unused_type, unused_attribute) {} template 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 inline typename enable_if< is_size_one_sequence >::type move_to(Iterator first, Iterator last, Dest& dest, tuple_attribute) { traits::move_to(first, last, fusion::front(dest)); } template inline void move_to(Iterator first, Iterator last, boost::iterator_range& rng, range_attribute) { rng = {first, last}; } } template inline void move_to(boost::optional&& src, Dest& dest) { if (src) detail::move_to(std::move(*src), dest , typename attribute_category::type()); } template inline void move_to(Source&& src, Dest& dest) { detail::move_to(std::move(src), dest , typename attribute_category::type()); } template inline void move_to(T& src, T& dest) { if (boost::addressof(src) != boost::addressof(dest)) dest = std::move(src); } template inline void move_to(T const& src, T& dest) { if (boost::addressof(src) != boost::addressof(dest)) dest = std::move(src); } template inline void move_to(T&& src, T& dest) { if (boost::addressof(src) != boost::addressof(dest)) dest = std::move(src); } template 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::type()); } }}}} #endif