Index: boost/unique_ptr.hpp
===================================================================
--- boost/unique_ptr.hpp	(revision 0)
+++ boost/unique_ptr.hpp	(revision 0)
@@ -0,0 +1,377 @@
+///////////////////////////////////////////////////////////////////////////////
+// unique_ptr.hpp header file
+//
+// Copyright 2009 Howard Hinnant.
+// 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)
+// See http://www.boost.org/libs/foreach for documentation
+
+// This is a C++03 emulation of std::unique_ptr placed in namespace boost.
+// Reference http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2800.pdf
+//   for the latest unique_ptr specification, and
+//   reference http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html
+//   for any pending issues against this specification.
+
+#ifndef BOOST_UNIQUE_PTR_HPP
+#define BOOST_UNIQUE_PTR_HPP
+
+#include <boost/utility/enable_if.hpp>
+#include <boost/type_traits.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/compressed_pair.hpp>
+#include <boost/mpl/if.hpp>
+
+namespace boost
+{
+
+// A fake, do-nothing move to handle move-ignorant types.
+//   Remove if you've got another definition to handle this.
+template <class T>
+inline
+T&
+move(T& t)
+{
+    return t;
+}
+
+template <class T>
+struct default_delete
+{
+    default_delete() {}
+    template <class U>
+        default_delete(const default_delete<U>&,
+            typename enable_if_c<is_convertible<U*, T*>::value>::type* = 0)
+        {}
+
+    void operator()(T* ptr) const
+    {
+        BOOST_STATIC_ASSERT(sizeof(T) > 0);
+        delete ptr;
+    }
+};
+
+template <class T>
+struct default_delete<T[]>
+{
+    void operator()(T* ptr) const
+    {
+        BOOST_STATIC_ASSERT(sizeof(T) > 0);
+        delete [] ptr;
+    }
+
+private:
+
+    template <class U> void operator()(U*) const;
+};
+
+namespace detail
+{
+
+typedef char one;
+struct two {one _[2];};
+
+namespace pointer_type_imp
+{
+
+template <class U> static two test(...);
+template <class U> static one test(typename U::pointer* = 0);
+
+}  // pointer_type_imp
+
+template <class T>
+struct has_pointer_type
+{
+    static const bool value = sizeof(pointer_type_imp::test<T>(0)) == 1;
+};
+
+namespace pointer_type_imp
+{
+
+template <class T, class D, bool = has_pointer_type<D>::value>
+struct pointer_type
+{
+    typedef typename D::pointer type;
+};
+
+template <class T, class D>
+struct pointer_type<T, D, false>
+{
+    typedef T* type;
+};
+
+}  // pointer_type_imp
+
+template <class T, class D>
+struct pointer_type
+{
+    typedef typename pointer_type_imp::pointer_type<T,
+        typename boost::remove_reference<D>::type>::type type;
+};
+
+}  // detail
+
+template <class T, class D = default_delete<T> >
+class unique_ptr
+{
+public:
+    typedef T element_type;
+    typedef D deleter_type;
+    typedef typename detail::pointer_type<element_type, deleter_type>::type pointer;
+
+private:
+    boost::compressed_pair<pointer, deleter_type> ptr_;
+
+    typedef typename add_reference<deleter_type>::type deleter_reference;
+    typedef typename add_reference<const deleter_type>::type deleter_const_reference;
+
+    struct nat {int for_bool_;};
+
+    unique_ptr(unique_ptr&);
+    unique_ptr& operator=(unique_ptr&);
+
+    class rv
+    {
+        unique_ptr& r_;
+    public:
+        explicit rv(unique_ptr& r) : r_(r) {}
+        unique_ptr* operator->() {return &r_;}
+    };
+
+public:
+    operator rv() {return rv(*this);}
+    unique_ptr(rv r) : ptr_(r->release(), move(r->get_deleter())) {}
+    unique_ptr& operator=(rv r)
+    {
+        reset(r->release());
+        ptr_.second() = move(r->get_deleter());
+        return *this;
+    }
+    friend unique_ptr move(unique_ptr& u) {return unique_ptr(rv(u));}
+    friend unique_ptr move(rv r)          {return unique_ptr(r);}
+
+    unique_ptr()
+        : ptr_(pointer(), deleter_type())
+        {
+            BOOST_STATIC_ASSERT(!is_pointer<deleter_type>::value);
+        }
+
+    explicit unique_ptr(pointer p)
+        : ptr_(p, deleter_type())
+        {
+            BOOST_STATIC_ASSERT(!is_pointer<deleter_type>::value);
+        }
+
+    unique_ptr(pointer p, typename mpl::if_<
+                             is_reference<D>,
+                             D,
+                             typename add_reference<const D>::type>::type d)
+            : ptr_(p, d) {}
+
+    template <class U, class E>
+        unique_ptr(unique_ptr<U, E> u,
+            typename enable_if_c
+                <
+                is_convertible<typename unique_ptr<U>::pointer, pointer>::value &&
+                is_convertible<E, deleter_type>::value &&
+                (
+                    !is_reference<deleter_type>::value ||
+                     is_same<deleter_type, E>::value
+                )
+                >::type* = 0)
+            : ptr_(u.release(), u.get_deleter()) {}
+
+    ~unique_ptr() {reset();}
+
+    unique_ptr& operator=(int nat::*)
+    {
+        reset();
+        return *this;
+    }
+
+    template <class U, class E>
+        unique_ptr&
+        operator=(unique_ptr<U, E> u)
+        {
+            reset(u.release());
+            ptr_.second() = move(u.get_deleter());
+            return *this;
+        }
+
+    typename add_reference<T>::type operator*() const {return *get();}
+    pointer operator->() const {return get();}
+    pointer get() const {return ptr_.first();}
+    deleter_reference       get_deleter()       {return ptr_.second();}
+    deleter_const_reference get_deleter() const {return ptr_.second();}
+    operator int nat::*() const {return get() ? &nat::for_bool_ : 0;}
+
+    void reset(pointer p = pointer())
+    {
+        pointer t = get();
+        if (t != pointer())
+            get_deleter()(t);
+        ptr_.first() = p;
+    }
+
+    pointer release()
+    {
+        pointer tmp = get();
+        ptr_.first() = pointer();
+        return tmp;
+    }
+
+    void swap(unique_ptr& u) {ptr_.swap(u.ptr_);}
+};
+
+template <class T, class D>
+class unique_ptr<T[], D>
+{
+public:
+    typedef T element_type;
+    typedef D deleter_type;
+    typedef typename detail::pointer_type<element_type, deleter_type>::type pointer;
+
+private:
+    boost::compressed_pair<pointer, deleter_type> ptr_;
+
+    typedef typename add_reference<deleter_type>::type deleter_reference;
+    typedef typename add_reference<const deleter_type>::type deleter_const_reference;
+
+    struct nat {int for_bool_;};
+
+    unique_ptr(unique_ptr&);
+    unique_ptr& operator=(unique_ptr&);
+
+    class rv
+    {
+        unique_ptr& r_;
+    public:
+        explicit rv(unique_ptr& r) : r_(r) {}
+        unique_ptr* operator->() {return &r_;}
+    };
+
+public:
+    operator rv() {return rv(*this);}
+    unique_ptr(rv r) : ptr_(r->release(), move(r->get_deleter())) {}
+    unique_ptr& operator=(rv r)
+    {
+        reset(r->release());
+        ptr_.second() = move(r->get_deleter());
+        return *this;
+    }
+    friend unique_ptr move(unique_ptr& u) {return unique_ptr(rv(u));}
+    friend unique_ptr move(rv r)          {return unique_ptr(r);}
+
+    unique_ptr()
+        : ptr_(pointer(), deleter_type())
+        {
+            BOOST_STATIC_ASSERT(!is_pointer<deleter_type>::value);
+        }
+
+    explicit unique_ptr(pointer p)
+        : ptr_(p, deleter_type())
+        {
+            BOOST_STATIC_ASSERT(!is_pointer<deleter_type>::value);
+        }
+
+    unique_ptr(pointer p, typename mpl::if_<
+                             is_reference<D>,
+                             D,
+                             typename add_reference<const D>::type>::type d)
+            : ptr_(p, d) {}
+
+    ~unique_ptr() {reset();}
+
+    unique_ptr& operator=(int nat::*)
+    {
+        reset();
+        return *this;
+    }
+
+    T& operator[](size_t i) const {return get()[i];}
+    pointer get() const {return ptr_.first();}
+    deleter_reference       get_deleter()       {return ptr_.second();}
+    deleter_const_reference get_deleter() const {return ptr_.second();}
+    operator int nat::*() const {return get() ? &nat::for_bool_ : 0;}
+
+    void reset(pointer p = pointer())
+    {
+        pointer t = get();
+        if (t != pointer())
+            get_deleter()(t);
+        ptr_.first() = p;
+    }
+
+    pointer release()
+    {
+        pointer tmp = get();
+        ptr_.first() = pointer();
+        return tmp;
+    }
+
+    void swap(unique_ptr& u) {ptr_.swap(u.ptr_);}
+private:
+    template <class U>
+        explicit unique_ptr(U,
+            typename enable_if_c<is_convertible<U, pointer>::value>::type* = 0);
+};
+
+template<class T, class D>
+inline
+void
+swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y)
+{
+    x.swap(y);
+}
+
+template<class T1, class D1, class T2, class D2>
+inline
+bool
+operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y)
+{
+    return x.get() == y.get();
+}
+
+template<class T1, class D1, class T2, class D2>
+inline
+bool
+operator!=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y)
+{
+    return !(x == y);
+}
+
+template<class T1, class D1, class T2, class D2> 
+inline
+bool
+operator<(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y)
+{
+    return x.get() < y.get();
+}
+
+template<class T1, class D1, class T2, class D2> 
+inline
+bool
+operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y)
+{
+    return !(y < x);
+}
+
+template<class T1, class D1, class T2, class D2> 
+inline
+bool
+operator>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y)
+{
+    return y < x;
+}
+
+template<class T1, class D1, class T2, class D2> 
+inline
+bool
+operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y)
+{
+    return !(x < y);
+}
+
+}  // boost
+
+#endif  // UNIQUE_PTR_HPP
Index: libs/smart_ptr/test/unique_ptr_nonmove_named.cpp
===================================================================
--- libs/smart_ptr/test/unique_ptr_nonmove_named.cpp	(revision 0)
+++ libs/smart_ptr/test/unique_ptr_nonmove_named.cpp	(revision 0)
@@ -0,0 +1,31 @@
+//
+//  unique_ptr_nonmove_named.cpp - a negative test for moving from named objects
+//
+//  Copyright 2008 Howard Hinnant
+//
+// 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)
+//
+
+#include <boost/unique_ptr.hpp>
+
+boost::unique_ptr<int> factory(int i)
+{
+    return boost::unique_ptr<int>(new int(i));
+}
+
+void client(boost::unique_ptr<int> p)
+{
+    // Ownership transferred into client
+}   // int deleted here
+
+int main()
+{
+    boost::unique_ptr<int> p = factory(2);
+    // *p == 2
+    p.reset(new int(3));
+    // *p == 3
+    // error: unique_ptr<T, D>::unique_ptr(unique_ptr<T, D>&) is private
+    client(p);
+}
Index: libs/smart_ptr/test/unique_ptr_malloc_free.cpp
===================================================================
--- libs/smart_ptr/test/unique_ptr_malloc_free.cpp	(revision 0)
+++ libs/smart_ptr/test/unique_ptr_malloc_free.cpp	(revision 0)
@@ -0,0 +1,19 @@
+//
+//  unique_ptr_malloc_free.cpp - a positive test for using malloc & free
+//
+//  Copyright 2008 Howard Hinnant
+//
+// 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)
+//
+
+#include <boost/unique_ptr.hpp>
+#include <cstdlib>
+
+int main()
+{
+    boost::unique_ptr<int, void (*)(void*)> p(
+        (int*)std::malloc(sizeof(int)), std::free);
+    *p = 1;
+}   // free(p.get())
Index: libs/smart_ptr/test/Jamfile.v2
===================================================================
--- libs/smart_ptr/test/Jamfile.v2	(revision 50450)
+++ libs/smart_ptr/test/Jamfile.v2	(working copy)
@@ -50,5 +50,9 @@
           [ run wp_convertible_test.cpp ]
           [ run ip_convertible_test.cpp ]
           [ run allocate_shared_test.cpp ]
+	  [ run unique_ptr_move_temps.cpp ]
+	  [ compile-fail unique_ptr_nonmove_named.cpp ]
+	  [ run unique_ptr_move_named.cpp ]
+	  [ run unique_ptr_malloc_free.cpp ]
         ;
 }
Index: libs/smart_ptr/test/unique_ptr_move_named.cpp
===================================================================
--- libs/smart_ptr/test/unique_ptr_move_named.cpp	(revision 0)
+++ libs/smart_ptr/test/unique_ptr_move_named.cpp	(revision 0)
@@ -0,0 +1,32 @@
+//
+//  unique_ptr_move_named.cpp - a positive test for explicitly moving from
+//                              named objects
+//
+//  Copyright 2008 Howard Hinnant
+//
+// 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)
+//
+
+#include <boost/unique_ptr.hpp>
+
+boost::unique_ptr<int> factory(int i)
+{
+    return boost::unique_ptr<int>(new int(i));
+}
+
+void client(boost::unique_ptr<int> p)
+{
+    // Ownership transferred into client
+}   // int deleted here
+
+int main()
+{
+    boost::unique_ptr<int> p = factory(2);
+    // *p == 2
+    p.reset(new int(3));
+    // *p == 3
+    client(move(p));  // ok now
+    // p is "null" here
+}
Index: libs/smart_ptr/test/unique_ptr_move_temps.cpp
===================================================================
--- libs/smart_ptr/test/unique_ptr_move_temps.cpp	(revision 0)
+++ libs/smart_ptr/test/unique_ptr_move_temps.cpp	(revision 0)
@@ -0,0 +1,30 @@
+//
+//  unique_ptr_move_temps.cpp - a positive test for moving from temporaries
+//
+//  Copyright 2008 Howard Hinnant
+//
+// 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)
+//
+
+#include <boost/unique_ptr.hpp>
+
+boost::unique_ptr<int> factory(int i)
+{
+    return boost::unique_ptr<int>(new int(i));
+}
+
+void client(boost::unique_ptr<int> p)
+{
+    // Ownership transferred into client
+}   // int deleted here
+
+int main()
+{
+    boost::unique_ptr<int> p = factory(2);
+    // *p == 2
+    p.reset(new int(3));
+    // *p == 3
+    client(factory(4));
+}

