Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-31 10:02:38

0001 /*=============================================================================
0002     Copyright (c) 2001-2014 Joel de Guzman
0003     Copyright (c) 2013 Agustin Berge
0004     http://spirit.sourceforge.net/
0005 
0006     Distributed under the Boost Software License, Version 1.0. (See accompanying
0007     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
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_) // src is not a single-element tuple
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_) // src is a single-element tuple
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             // dest is a variant, src is a single element fusion sequence that the variant
0123             // cannot directly hold. We'll try to unwrap the single element fusion sequence.
0124             
0125             // Make sure that the Dest variant can really hold Source
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             // dest is a variant, src is a single element fusion sequence that the variant
0137             // *can* directly hold.
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         // $$$ Use std::move_iterator when iterator is not a const-iterator $$$
0224         detail::move_to(first, last, dest, typename attribute_category<Dest>::type());
0225     }
0226 }}}}
0227 
0228 #endif