Squashed 'third_party/boostorg/move/' content from commit d503fbe

Change-Id: I5f8ac37161a1044b02ffb1f59cf15622fc6acd17
git-subtree-dir: third_party/boostorg/move
git-subtree-split: d503fbe1c8334fa8885e67cb83c96aeaf3938555
diff --git a/test/unique_ptr_test_utils_beg.hpp b/test/unique_ptr_test_utils_beg.hpp
new file mode 100644
index 0000000..965732c
--- /dev/null
+++ b/test/unique_ptr_test_utils_beg.hpp
@@ -0,0 +1,209 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Howard Hinnant 2009
+// (C) Copyright Ion Gaztanaga 2014-2014.
+//
+// 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/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#ifndef BOOST_MOVE_UNIQUE_PTR_TEST_UTILS_BEG_HPP
+#define BOOST_MOVE_UNIQUE_PTR_TEST_UTILS_BEG_HPP
+#include <boost/move/core.hpp>
+#include <boost/move/detail/unique_ptr_meta_utils.hpp>
+#include <boost/static_assert.hpp>
+
+//////////////////////////////////////////////
+//
+// The initial implementation of these tests
+// was written by Howard Hinnant. 
+//
+// These test were later refactored grouping
+// and porting them to Boost.Move.
+//
+// Many thanks to Howard for releasing his C++03
+// unique_ptr implementation with such detailed
+// test cases.
+//
+//////////////////////////////////////////////
+
+//A deleter that can only default constructed
+template <class T>
+class def_constr_deleter
+{
+   int state_;
+   def_constr_deleter(const def_constr_deleter&);
+   def_constr_deleter& operator=(const def_constr_deleter&);
+
+   public:
+   typedef typename ::boost::move_upmu::remove_extent<T>::type element_type;
+   static const bool is_array = ::boost::move_upmu::is_array<T>::value;
+
+   def_constr_deleter() : state_(5) {}
+
+   explicit def_constr_deleter(int s) : state_(s) {}
+
+   int state() const {return state_;}
+
+   void set_state(int s) {state_ = s;}
+
+   void operator()(element_type* p) const
+   {  is_array ? delete []p : delete p;   }
+
+   void operator()(element_type* p)
+   {  ++state_;   is_array ? delete []p : delete p;  }
+};
+
+//A deleter that can be copy constructed
+template <class T>
+class copy_constr_deleter
+{
+   int state_;
+
+   public:
+   typedef typename ::boost::move_upmu::remove_extent<T>::type element_type;
+   static const bool is_array = ::boost::move_upmu::is_array<T>::value;
+
+   copy_constr_deleter() : state_(5) {}
+
+   template<class U>
+   copy_constr_deleter(const copy_constr_deleter<U>&
+      , typename boost::move_upd::enable_def_del<U, T>::type* =0)
+   {  state_ = 5; }
+
+   explicit copy_constr_deleter(int s) : state_(s) {}
+
+   template <class U>
+   typename boost::move_upd::enable_def_del<U, T, copy_constr_deleter&>::type
+      operator=(const copy_constr_deleter<U> &d)
+   {
+      state_ = d.state();
+      return *this;
+   }
+
+   int state() const          {return state_;}
+
+   void set_state(int s)      {state_ = s;}
+
+   void operator()(element_type* p) const
+   {  is_array ? delete []p : delete p;   }
+
+   void operator()(element_type* p)
+   {  ++state_;   is_array ? delete []p : delete p;  }
+};
+
+//A deleter that can be only move constructed
+template <class T>
+class move_constr_deleter
+{
+   int state_;
+
+   BOOST_MOVABLE_BUT_NOT_COPYABLE(move_constr_deleter)
+
+   public:
+   typedef typename ::boost::move_upmu::remove_extent<T>::type element_type;
+   static const bool is_array = ::boost::move_upmu::is_array<T>::value;
+
+   move_constr_deleter() : state_(5) {}
+
+   move_constr_deleter(BOOST_RV_REF(move_constr_deleter) r)
+      : state_(r.state_)
+   {  r.state_ = 0;  }
+
+   explicit move_constr_deleter(int s) : state_(s) {}
+
+   template <class U>
+   move_constr_deleter(BOOST_RV_REF(move_constr_deleter<U>) d
+      , typename boost::move_upd::enable_def_del<U, T>::type* =0)
+      : state_(d.state())
+   { d.set_state(0);  }
+
+   move_constr_deleter& operator=(BOOST_RV_REF(move_constr_deleter) r)
+   {
+      state_ = r.state_;
+      r.state_ = 0;
+      return *this;
+   }
+
+   template <class U>
+   typename boost::move_upd::enable_def_del<U, T, move_constr_deleter&>::type
+      operator=(BOOST_RV_REF(move_constr_deleter<U>) d)
+   {
+      state_ = d.state();
+      d.set_state(0);
+      return *this;
+   }
+
+   int state() const          {return state_;}
+
+   void set_state(int s)      {state_ = s;}
+
+   void operator()(element_type* p) const
+   {  is_array ? delete []p : delete p;   }
+
+   void operator()(element_type* p)
+   {  ++state_;   is_array ? delete []p : delete p;  }
+
+   friend bool operator==(const move_constr_deleter& x, const move_constr_deleter& y)
+      {return x.state_ == y.state_;}
+};
+
+//A base class containing state with a static instance counter
+struct A
+{
+   int state_;
+   static int count;
+
+   A()               : state_(999)      {++count;}
+   explicit A(int i) : state_(i)        {++count;}
+   A(const A& a)     : state_(a.state_) {++count;}
+   A& operator=(const A& a) { state_ = a.state_; return *this; }
+   void set(int i)   {state_ = i;}
+   virtual ~A()      {--count;}
+   friend bool operator==(const A& x, const A& y) { return x.state_ == y.state_; }
+};
+
+int A::count = 0;
+
+//A class derived from A with a static instance counter
+struct B
+   : public A
+{
+   static int count;
+   B() : A() {++count;}
+   B(const B &b) : A(b) {++count;}
+   virtual ~B() {--count;}
+};
+
+int B::count = 0;
+
+void reset_counters();
+
+BOOST_STATIC_ASSERT((::boost::move_upmu::is_convertible<B, A>::value));
+
+//Incomplete Type function declarations
+struct I;
+void check(int i);
+I* get();
+I* get_array(int i);
+
+#include <boost/move/unique_ptr.hpp>
+
+template <class T, class D = ::boost::movelib::default_delete<T> >
+struct J
+{
+   typedef boost::movelib::unique_ptr<T, D> unique_ptr_type;
+   typedef typename unique_ptr_type::element_type element_type;
+   boost::movelib::unique_ptr<T, D> a_;
+   J() {}
+   explicit J(element_type*a) : a_(a) {}
+   ~J();
+
+   element_type* get() const {return a_.get();}
+   D& get_deleter() {return a_.get_deleter();}
+};
+
+#endif   //BOOST_MOVE_UNIQUE_PTR_TEST_UTILS_BEG_HPP