stlab.adobe.com Adobe Systems Incorporated

move.hpp

Go to the documentation of this file.
00001 /*
00002     Copyright 2005-2007 Adobe Systems Incorporated
00003     Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt
00004     or a copy at http://stlab.adobe.com/licenses.html)
00005 */
00006 
00007 /*************************************************************************************************/
00008 
00009 #ifndef ADOBE_MOVE_HPP
00010 #define ADOBE_MOVE_HPP
00011 
00012 #include <cassert>
00013 #include <iterator>
00014 #include <memory>
00015 
00016 #include <boost/iterator/iterator_adaptor.hpp>
00017 #include <boost/mpl/bool.hpp>
00018 #include <boost/mpl/and.hpp>
00019 #include <boost/mpl/or.hpp>
00020 #include <boost/mpl/not.hpp>
00021 #include <boost/mpl/assert.hpp>
00022 #include <boost/range/begin.hpp>
00023 #include <boost/range/end.hpp>
00024 #include <boost/type_traits/is_convertible.hpp>
00025 #include <boost/type_traits/is_same.hpp>
00026 #include <boost/type_traits/is_class.hpp>
00027 #include <boost/utility/enable_if.hpp>
00028 
00247 /*************************************************************************************************/
00248 
00249 namespace adobe {
00250 
00251 /*************************************************************************************************/
00252 
00253 namespace implementation {
00254 
00255 /*************************************************************************************************/
00256 
00257 template <typename T>  
00258 struct class_has_move_assign {  
00259     class type {
00260         typedef T& (T::*E)(T t);  
00261         typedef char (&no_type)[1];  
00262         typedef char (&yes_type)[2];  
00263         template <E e> struct sfinae { typedef yes_type type; };  
00264         template <class U>  
00265         static typename sfinae<&U::operator=>::type test(int);  
00266         template <class U>  
00267         static no_type test(...);  
00268     public:  
00269         enum {value = sizeof(test<T>(1)) == sizeof(yes_type)};  
00270     };
00271  };  
00272 
00273 /*************************************************************************************************/
00274 
00275 template<typename T>
00276 struct has_move_assign : boost::mpl::and_<boost::is_class<T>, class_has_move_assign<T> > {};
00277 
00278 /*************************************************************************************************/
00279 
00280 class test_can_convert_anything { };
00281 
00282 /*************************************************************************************************/
00283 
00284 } //namespace implementation
00285 
00286 
00287 /*************************************************************************************************/
00288 
00289 /*
00290     REVISIT (sparent@adobe.com): This is a work around for Boost 1.34.1 and VC++ 2008 where
00291     boost::is_convertible<T, T> fails to compile.
00292 */
00293 
00294 template <typename T, typename U>
00295 struct is_convertible : boost::mpl::or_<
00296     boost::is_same<T, U>,
00297     boost::is_convertible<T, U>
00298 > { };
00299 
00305 template <typename T>
00306 struct move_from
00307 {
00308     explicit move_from(T& x) : source(x) { }
00309     T& source;
00310 };
00311 
00316 template <typename T>
00317 struct is_movable : boost::mpl::and_<
00318                         boost::is_convertible<move_from<T>, T>,
00319                         implementation::has_move_assign<T>,
00320                         boost::mpl::not_<boost::is_convertible<implementation::test_can_convert_anything, T> >
00321                     > { };
00322 
00323 /*************************************************************************************************/
00324 
00332 template <typename T,
00333           typename U = T,
00334           typename R = void*>
00335 struct copy_sink : boost::enable_if<
00336                         boost::mpl::and_<
00337                             adobe::is_convertible<T, U>,                           
00338                             boost::mpl::not_<is_movable<T> >
00339                         >,
00340                         R
00341                     >
00342 { };
00343 
00344 /*************************************************************************************************/
00345 
00353 template <typename T,
00354           typename U = T,
00355           typename R = void*>
00356 struct move_sink : boost::enable_if<
00357                         boost::mpl::and_<
00358                             adobe::is_convertible<T, U>,                            
00359                             is_movable<T>
00360                         >,
00361                         R
00362                     >
00363 { };
00364 
00365 /*************************************************************************************************/
00366 
00374 template <typename T>
00375 T move(T& x, typename move_sink<T>::type = 0) { return T(move_from<T>(x)); }
00376 
00377 /*************************************************************************************************/
00378 
00384 template <typename T>
00385 T& move(T& x, typename copy_sink<T>::type = 0) { return x; }
00386 
00387 /*************************************************************************************************/
00388 
00394 template <typename I, // I models InputIterator
00395           typename O> // O models OutputIterator
00396 O move(I f, I l, O result)
00397 {
00398     while (f != l) {
00399         *result = adobe::move(*f);
00400         ++f; ++result;
00401     }
00402     return result;
00403 }
00404 
00405 /*************************************************************************************************/
00406 
00412 template <typename I, // I models InputRange
00413           typename O> // O models OutputIterator
00414 inline O move(I& in, O out) { return adobe::move(boost::begin(in), boost::end(in), out); }
00415 
00416 /*************************************************************************************************/
00417  
00423 template <typename I, // I models BidirectionalIterator
00424           typename O> // O models BidirectionalIterator
00425 O move_backward(I f, I l, O result)
00426 {
00427     while (f != l) {
00428         --l; --result;
00429         *result = adobe::move(*l);
00430     }
00431     return result;
00432 }
00433 
00434 /*************************************************************************************************/
00435 
00441 template <typename I, // I models BidirectionalRange
00442           typename O> // O models BidirectionalIterator
00443 inline O move_backward(I& in, O out)
00444 { return move_backward(boost::begin(in), boost::end(in), out); }
00445 
00446 /*************************************************************************************************/
00447 
00454 template <typename C> // C models Container
00455 class back_move_iterator : public std::iterator<std::output_iterator_tag, void, void, void, void>
00456 {
00457     C* container_m;
00458     
00459  public:
00460     typedef C container_type;
00461     
00462     explicit back_move_iterator(C& x) : container_m(&x) { }
00463     
00464     back_move_iterator& operator=(typename C::value_type x)
00465     { container_m->push_back(adobe::move(x)); return *this; }
00466     
00467     back_move_iterator& operator*() { return *this; }
00468     back_move_iterator& operator++() { return *this; }
00469     back_move_iterator& operator++(int) { return *this; }
00470 };
00471 
00472 /*************************************************************************************************/
00473 
00480 template <typename C> // C models Container
00481 inline back_move_iterator<C> back_mover(C& x) { return back_move_iterator<C>(x); }
00482 
00483 /*************************************************************************************************/
00484 
00485 } // namespace adobe
00486 
00487 /*************************************************************************************************/
00488 
00489 #endif
00490 
00491 /*************************************************************************************************/

Copyright © 2006-2007 Adobe Systems Incorporated.

Use of this website signifies your agreement to the Terms of Use and Online Privacy Policy.

Search powered by Google