Added to trunk

[SVN r70067]
This commit is contained in:
Ion Gaztañaga
2011-03-17 16:41:04 +00:00
parent 3362ca85e6
commit d4983b7afe
53 changed files with 5652 additions and 0 deletions
+28
View File
@@ -0,0 +1,28 @@
##############################################################################
##
## (C) Copyright Ion Gaztanaga 2008-2009 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)
##
##
##############################################################################
rule test_all
{
local all_rules = ;
for local fileb in [ glob *.cpp ]
{
all_rules += [ run $(fileb)
: # additional args
: # test-files
: # requirements
] ;
}
return $(all_rules) ;
}
test-suite move_example : [ test_all r ]
: <link>static
;
+46
View File
@@ -0,0 +1,46 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2009.
// 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_TEST_COPYMOVABLE_HPP
#define BOOST_MOVE_TEST_COPYMOVABLE_HPP
//[movable_definition
//header file "copy_movable.hpp"
#include <boost/move/move.hpp>
//A copy_movable class
class copy_movable
{
BOOST_COPYABLE_AND_MOVABLE(copy_movable)
int value_;
public:
copy_movable() : value_(1){}
//Move constructor and assignment
copy_movable(BOOST_RV_REF(copy_movable) m)
{ value_ = m.value_; m.value_ = 0; }
copy_movable(const copy_movable &m)
{ value_ = m.value_; }
copy_movable & operator=(BOOST_RV_REF(copy_movable) m)
{ value_ = m.value_; m.value_ = 0; return *this; }
copy_movable & operator=(BOOST_COPY_ASSIGN_REF(copy_movable) m)
{ value_ = m.value_; return *this; }
bool moved() const //Observer
{ return value_ == 0; }
};
//]
#endif //BOOST_MOVE_TEST_COPYMOVABLE_HPP
+152
View File
@@ -0,0 +1,152 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2009.
// 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.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/move/move.hpp>
//[clone_ptr_base_derived
class Base
{
BOOST_COPYABLE_AND_MOVABLE(Base)
public:
Base(){}
// Compiler-generated copy constructor...
Base(BOOST_RV_REF(Base) x) {/**/} // Move ctor
Base& operator=(BOOST_RV_REF(Base) x)
{/**/ return *this;} // Move assign
Base& operator=(BOOST_COPY_ASSIGN_REF(Base) x)
{/**/ return *this;} // Copy assign
virtual Base *clone() const
{ return new Base(*this); }
};
class Member
{
BOOST_COPYABLE_AND_MOVABLE(Member)
public:
Member(){}
// Compiler-generated copy constructor...
Member(BOOST_RV_REF(Member)) {/**/} // Move ctor
Member &operator=(BOOST_RV_REF(Member)) // Move assign
{/**/ return *this; }
Member &operator=(BOOST_COPY_ASSIGN_REF(Member)) // Copy assign
{/**/ return *this; }
};
class Derived : public Base
{
BOOST_COPYABLE_AND_MOVABLE(Derived)
Member mem_;
public:
Derived(){}
// Compiler-generated copy constructor...
Derived(BOOST_RV_REF(Derived) x) // Move ctor
: Base(boost::move(static_cast<Base&>(x))),
mem_(boost::move(x.mem_)) { }
Derived& operator=(BOOST_RV_REF(Derived) x) // Move assign
{
Base::operator=(boost::move(static_cast<Base&>(x)));
mem_ = boost::move(x.mem_);
return *this;
}
Derived& operator=(BOOST_COPY_ASSIGN_REF(Derived) x) // Copy assign
{
Base::operator=(static_cast<const Base&>(x));
mem_ = x.mem_;
return *this;
}
// ...
};
//]
//[clone_ptr_def
template <class T>
class clone_ptr
{
private:
// Mark this class copyable and movable
BOOST_COPYABLE_AND_MOVABLE(clone_ptr)
T* ptr;
public:
// Construction
explicit clone_ptr(T* p = 0) : ptr(p) {}
// Destruction
~clone_ptr() { delete ptr; }
clone_ptr(const clone_ptr& p) // Copy constructor (as usual)
: ptr(p.ptr ? p.ptr->clone() : 0) {}
clone_ptr& operator=(BOOST_COPY_ASSIGN_REF(clone_ptr) p) // Copy assignment
{
if (this != &p){
T *tmp_p = p.ptr ? p.ptr->clone() : 0;
delete ptr;
ptr = tmp_p;
}
return *this;
}
//Move semantics...
clone_ptr(BOOST_RV_REF(clone_ptr) p) //Move constructor
: ptr(p.ptr) { p.ptr = 0; }
clone_ptr& operator=(BOOST_RV_REF(clone_ptr) p) //Move assignment
{
if (this != &p){
delete ptr;
ptr = p.ptr;
p.ptr = 0;
}
return *this;
}
};
//]
int main()
{
{
//[copy_clone_ptr
clone_ptr<Base> p1(new Derived());
// ...
clone_ptr<Base> p2 = p1; // p2 and p1 each own their own pointer
//]
}
{
//[move_clone_ptr
clone_ptr<Base> p1(new Derived());
// ...
clone_ptr<Base> p2 = boost::move(p1); // p2 now owns the pointer instead of p1
p2 = clone_ptr<Base>(new Derived()); // temporary is moved to p2
}
//]
//[clone_ptr_move_derived
Derived d;
Derived d2(boost::move(d));
d2 = boost::move(d);
//]
return 0;
}
+105
View File
@@ -0,0 +1,105 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright David Abrahams, Vicente Botet, Ion Gaztanaga 2009.
// 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.
//
//////////////////////////////////////////////////////////////////////////////
//[construct_forward_example
#include <boost/move/move.hpp>
#include <iostream>
class copyable_only_tester
{
public:
copyable_only_tester()
{ std::cout << "copyable_only_tester()" << std::endl; }
copyable_only_tester(const copyable_only_tester&)
{ std::cout << "copyable_only_tester(const copyable_only_tester&)" << std::endl; }
copyable_only_tester(int)
{ std::cout << "copyable_only_tester(int)" << std::endl; }
copyable_only_tester(int, double)
{ std::cout << "copyable_only_tester(int, double)" << std::endl; }
};
class copyable_movable_tester
{
// move semantics
BOOST_COPYABLE_AND_MOVABLE(copyable_movable_tester)
public:
copyable_movable_tester()
{ std::cout << "copyable_movable_tester()" << std::endl; }
copyable_movable_tester(int)
{ std::cout << "copyable_movable_tester(int)" << std::endl; }
copyable_movable_tester(BOOST_RV_REF(copyable_movable_tester))
{ std::cout << "copyable_movable_tester(BOOST_RV_REF(copyable_movable_tester))" << std::endl; }
copyable_movable_tester(const copyable_movable_tester &)
{ std::cout << "copyable_movable_tester(const copyable_movable_tester &)" << std::endl; }
copyable_movable_tester(BOOST_RV_REF(copyable_movable_tester), BOOST_RV_REF(copyable_movable_tester))
{ std::cout << "copyable_movable_tester(BOOST_RV_REF(copyable_movable_tester), BOOST_RV_REF(copyable_movable_tester))" << std::endl; }
copyable_movable_tester &operator=(BOOST_RV_REF(copyable_movable_tester))
{ std::cout << "copyable_movable_tester & operator=(BOOST_RV_REF(copyable_movable_tester))" << std::endl;
return *this; }
copyable_movable_tester &operator=(BOOST_COPY_ASSIGN_REF(copyable_movable_tester))
{ std::cout << "copyable_movable_tester & operator=(BOOST_COPY_ASSIGN_REF(copyable_movable_tester))" << std::endl;
return *this; }
};
//1 argument
template<class MaybeMovable, class MaybeRv>
void function_construct(BOOST_FWD_REF(MaybeRv) x)
{ MaybeMovable m(boost::forward<MaybeRv>(x)); }
//2 argument
template<class MaybeMovable, class MaybeRv, class MaybeRv2>
void function_construct(BOOST_FWD_REF(MaybeRv) x, BOOST_FWD_REF(MaybeRv2) x2)
{ MaybeMovable m(boost::forward<MaybeRv>(x), boost::forward<MaybeRv2>(x2)); }
int main()
{
copyable_movable_tester m;
//move constructor
function_construct<copyable_movable_tester>(boost::move(m));
//copy constructor
function_construct<copyable_movable_tester>(copyable_movable_tester());
//two rvalue constructor
function_construct<copyable_movable_tester>(boost::move(m), boost::move(m));
copyable_only_tester nm;
//copy constructor (copyable_only_tester has no move ctor.)
function_construct<copyable_only_tester>(boost::move(nm));
//copy constructor
function_construct<copyable_only_tester>(nm);
//int constructor
function_construct<copyable_only_tester>(int(0));
//int, double constructor
function_construct<copyable_only_tester>(int(0), double(0.0));
//Output is:
//copyable_movable_tester()
//copyable_movable_tester(BOOST_RV_REF(copyable_movable_tester))
//copyable_movable_tester()
//copyable_movable_tester(const copyable_movable_tester &)
//copyable_movable_tester(BOOST_RV_REF(copyable_movable_tester), BOOST_RV_REF(copyable_movable_tester))
//copyable_only_tester()
//copyable_only_tester(const copyable_only_tester&)
//copyable_only_tester(const copyable_only_tester&)
//copyable_only_tester(int)
//copyable_only_tester(int, double)
return 0;
}
//]
+87
View File
@@ -0,0 +1,87 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2008-2009.
// 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.
//
//////////////////////////////////////////////////////////////////////////////
//[file_descriptor_def
#include <boost/move/move.hpp>
#include <stdexcept>
class file_descriptor
{
//<-
int operating_system_open_file(const char *)
{
return 1;
}
void operating_system_close_file(int)
{}
//->
int os_descr_;
private:
BOOST_MOVABLE_BUT_NOT_COPYABLE(file_descriptor)
public:
explicit file_descriptor(const char *filename = 0) //Constructor
: os_descr_(filename ? operating_system_open_file(filename) : 0)
{ if(!os_descr_) throw std::runtime_error("file not found"); }
~file_descriptor() //Destructor
{ if(!os_descr_) operating_system_close_file(os_descr_); }
file_descriptor(BOOST_RV_REF(file_descriptor) x) // Move ctor
: os_descr_(x.os_descr_)
{ x.os_descr_ = 0; }
file_descriptor& operator=(BOOST_RV_REF(file_descriptor) x) // Move assign
{
if(!os_descr_) operating_system_close_file(os_descr_);
os_descr_ = x.os_descr_;
x.os_descr_ = 0;
return *this;
}
bool empty() const { return os_descr_ == 0; }
};
//]
//[file_descriptor_example
#include <boost/interprocess/containers/vector.hpp>
#include <cassert>
//Remember: 'file_descriptor' is NOT copyable, but it
//can be returned from functions thanks to move semantics
file_descriptor create_file_descriptor(const char *filename)
{ return file_descriptor(filename); }
int main()
{
//Open a file obtaining its descriptor, the temporary
//returned from 'create_file_descriptor' is moved to 'fd'.
file_descriptor fd = create_file_descriptor("filename");
assert(!fd.empty());
//Now move fd into a vector
boost::interprocess::vector<file_descriptor> v;
v.push_back(boost::move(fd));
//Check ownership has been transferred
assert(fd.empty());
assert(!v[0].empty());
//Compilation error if uncommented since file_descriptor is not copyable
//and vector copy construction requires value_type's copy constructor:
//boost::interprocess::vector<file_descriptor> v2(v);
return 0;
}
//]
+60
View File
@@ -0,0 +1,60 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2009.
// 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.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/config.hpp>
#if !defined(BOOST_NO_RVALUE_REFERENCES)
int main()
{
return 0;
}
#else
//[how_works_example
#include <boost/move/move.hpp>
#include <iostream>
class sink_tester
{
public: //conversions provided by BOOST_COPYABLE_AND_MOVABLE
operator ::boost::rv<sink_tester>&()
{ return *static_cast< ::boost::rv<sink_tester>* >(this); }
operator const ::boost::rv<sink_tester>&() const
{ return *static_cast<const ::boost::rv<sink_tester>* >(this); }
};
//Functions returning different r/lvalue types
sink_tester rvalue() { return sink_tester(); }
const sink_tester const_rvalue() { return sink_tester(); }
sink_tester & lvalue() { static sink_tester lv; return lv; }
const sink_tester & const_lvalue() { static const sink_tester clv = sink_tester(); return clv; }
//BOOST_RV_REF overload
void sink(::boost::rv<sink_tester> &) { std::cout << "non-const rvalue catched" << std::endl; }
//BOOST_COPY_ASSIGN_REF overload
void sink(const ::boost::rv<sink_tester> &){ std::cout << "const (r-l)value catched" << std::endl; }
//Overload provided by BOOST_COPYABLE_AND_MOVABLE
void sink(sink_tester &) { std::cout << "non-const lvalue catched" << std::endl; }
int main()
{
sink(const_rvalue()); //"const (r-l)value catched"
sink(const_lvalue()); //"const (r-l)value catched"
sink(lvalue()); //"non-const lvalue catched"
sink(rvalue()); //"non-const rvalue catched"
return 0;
}
//]
#endif
+41
View File
@@ -0,0 +1,41 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2009.
// 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.
//
//////////////////////////////////////////////////////////////////////////////
//[move_algorithms_example
#include "movable.hpp"
#include <cassert>
#include <boost/aligned_storage.hpp>
int main()
{
const std::size_t ArraySize = 10;
movable movable_array[ArraySize];
movable movable_array2[ArraySize];
//move
boost::move(&movable_array2[0], &movable_array2[ArraySize], &movable_array[0]);
assert(movable_array2[0].moved());
assert(!movable_array[0].moved());
//move backward
boost::move_backward(&movable_array[0], &movable_array[ArraySize], &movable_array2[ArraySize]);
assert(movable_array[0].moved());
assert(!movable_array2[0].moved());
//uninitialized_move
boost::aligned_storage< sizeof(movable)*ArraySize
, boost::alignment_of<movable>::value>::type storage;
movable *raw_movable = static_cast<movable*>(static_cast<void*>(&storage));
boost::uninitialized_move(&movable_array2[0], &movable_array2[ArraySize], raw_movable);
assert(movable_array2[0].moved());
assert(!raw_movable[0].moved());
return 0;
}
//]
+48
View File
@@ -0,0 +1,48 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2009.
// 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.
//
//////////////////////////////////////////////////////////////////////////////
//[move_inserter_example
#include <boost/interprocess/containers/list.hpp>
#include "movable.hpp"
#include <cassert>
using namespace ::boost::interprocess;
typedef list<movable> list_t;
typedef list_t::iterator l_iterator;
template<class MoveInsertIterator>
void test_move_inserter(list_t &l2, MoveInsertIterator mit)
{
//Create a list with 10 default constructed objects
list<movable> l(10);
assert(!l.begin()->moved());
l2.clear();
//Move construct
for(l_iterator itbeg = l.begin(), itend = l.end(); itbeg != itend; ++itbeg){
*mit = *itbeg;
}
//Check size and status
assert(l2.size() == l.size());
assert(l.begin()->moved());
assert(!l2.begin()->moved());
}
int main()
{
list_t l2;
test_move_inserter(l2, boost::back_move_inserter(l2));
test_move_inserter(l2, boost::front_move_inserter(l2));
test_move_inserter(l2, boost::move_inserter(l2, l2.end()));
return 0;
}
//]
+39
View File
@@ -0,0 +1,39 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2009.
// 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.
//
//////////////////////////////////////////////////////////////////////////////
//[move_iterator_example
#include <boost/interprocess/containers/vector.hpp>
#include "movable.hpp"
#include <cassert>
int main()
{
using namespace ::boost::interprocess;
//Create a vector with 10 default constructed objects
vector<movable> v(10);
assert(!v[0].moved());
//Move construct all elements in v into v2
vector<movable> v2( boost::make_move_iterator(v.begin())
, boost::make_move_iterator(v.end()));
assert(v[0].moved());
assert(!v2[0].moved());
//Now move assign all elements from in v2 back into v
v.assign( boost::make_move_iterator(v2.begin())
, boost::make_move_iterator(v2.end()));
assert(v2[0].moved());
assert(!v[0].moved());
return 0;
}
//]
+49
View File
@@ -0,0 +1,49 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2009.
// 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_TEST_MOVABLE_HPP
#define BOOST_MOVE_TEST_MOVABLE_HPP
//[movable_definition
//header file "movable.hpp"
#include <boost/move/move.hpp>
//A movable class
class movable
{
BOOST_MOVABLE_BUT_NOT_COPYABLE(movable)
int value_;
public:
movable() : value_(1){}
//Move constructor and assignment
movable(BOOST_RV_REF(movable) m)
{ value_ = m.value_; m.value_ = 0; }
movable & operator=(BOOST_RV_REF(movable) m)
{ value_ = m.value_; m.value_ = 0; return *this; }
bool moved() const //Observer
{ return value_ == 0; }
};
namespace boost{
template<>
struct has_nothrow_move<movable>
{
static const bool value = true;
};
} //namespace boost{
//]
#endif //BOOST_MOVE_TEST_MOVABLE_HPP