Boost logo

Boost :

Subject: Re: [boost] [move] Unifying move emulation code in boost
From: Ion Gaztañaga (igaztanaga_at_[hidden])
Date: 2009-01-05 08:46:19


Anthony Williams wrote:
> Ion Gaztañaga <igaztanaga_at_[hidden]> writes:
>
>> I've written (attached) a small, surely not complete, but usable
>> boost/move.hpp header (ok, it could go to boost/detail/move.hpp until
>> a decent review is done) that is tested with a movable class in the
>> file movable_test.cpp, both with Visual 7.1 and move-enabled GCC 4.3.
>
> This is almost identical to the boost.thread move emulation. In
> Boost.thread, rv<T> is boost::detail::thread_move_t<T>, but most of
> the other stuff is equivalent.

I was having some problems with some of Interprocess movable classes and
Visual 7.1. I just changed is_movable conversion check from T& -> rv<T>
to T -> rv<T> and my problems disappeared. I don't know if that would
break some existing code, though:

template<class T>
class is_movable
{
    public:
    static const bool value =
       boost::is_convertible<T, detail::rv<T> >::value;
};

> If there is support for this as a basis for combined support, I can
> easily rework boost.thread to use it.

That's the idea. I attach a newer version that uses the modified
is_movable trait, pushes rv to namespace detail and uses
boost::addressof() to implement operator ->().

Regards,

Ion


// 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)
// (C) Copyright 2007-8 Anthony Williams
// (C) Copyright 2009 Howard Hinnant
// (C) Copyright 2009 Ion Gaztanaga

#include <boost/config.hpp>
#include <boost/type_traits/is_convertible.hpp>

#ifndef BOOST_MOVE_HPP
#define BOOST_MOVE_HPP

#ifndef BOOST_HAS_RVALUE_REFS

#ifndef BOOST_NO_SFINAE
#include <boost/utility/enable_if.hpp>
#endif

#include <boost/utility/addressof.hpp>

#else //#ifndef BOOST_HAS_RVALUE_REFS

#include <boost/type_traits/remove_reference.hpp>

#endif

namespace boost {

#include <boost/config/abi_prefix.hpp>

#ifndef BOOST_HAS_RVALUE_REFS

namespace detail {

template<class T>
class rv
{
   private:
   rv &operator=(const rv&);
   
   T& r_;
   public:
   explicit rv(T& r) : r_(r) {}
   T* operator->() {return boost::addressof(r_);}
   T& operator*() {return r_;}
};

} //namespace detail

template<class T>
class is_movable
{
   public:
   static const bool value = boost::is_convertible<T, detail::rv<T> >::value;
};


#ifndef BOOST_NO_SFINAE
template<typename T>
typename boost::enable_if<boost::is_movable<T>, T>::type move(T& t)
{
   return T(detail::rv<T>(t));
}
#endif
    
template<typename T>
detail::rv<T> move(detail::rv<T> t)
{ return t; }

#define BOOST_ENABLE_MOVE_EMULATION(TYPE)\
   operator boost::detail::rv<TYPE>() \
   { return boost::detail::rv<TYPE>(*this); }\
//

#define BOOST_SWAP_BASED_MOVE_ASSIGN(TYPE)\
   TYPE& operator=(boost::detail::rv<TYPE> r) \
   { \
      TYPE tmp(r); \
      this->swap(tmp); \
      return *this; \
   } \
//

#else //#ifndef BOOST_HAS_RVALUE_REFS

#define BOOST_ENABLE_MOVE_EMULATION(TYPE)\
//

#define BOOST_SWAP_BASED_MOVE_ASSIGN(TYPE)\
   TYPE& operator=(TYPE &&r) \
   { \
      TYPE tmp(boost::move(r)); \
      this->swap(tmp); \
      return *this; \
   } \
//

template <class T>
struct move_identity_type
{
   typedef T type;
};

template <class T>
inline T&& forward(typename boost::move_identity_type<T>::type&& t)
{ return t; }

template <class T>
inline typename boost::remove_reference<T>::type&& move(T&& t)
{ return t; }

template <class T, class U>
class move_is_convertible
{
   typedef char true_t;
   class false_t { char dummy[2]; };
   static true_t dispatch(U);
   static false_t dispatch(...);
   static T trigger();
   public:
   enum { value = sizeof(dispatch(trigger())) == sizeof(true_t) };
};


template<class T>
class is_movable
{
   public:
   static const bool value = move_is_convertible<T&&, T>::value;
};


#endif //#ifndef BOOST_HAS_RVALUE_REFS

#include <boost/config/abi_suffix.hpp>

} //namespace boost {


#endif //#ifndef BOOST_MOVE_HPP



Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk