diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 18:24:20 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 18:24:20 +0000 |
commit | 483eb2f56657e8e7f419ab1a4fab8dce9ade8609 (patch) | |
tree | e5d88d25d870d5dedacb6bbdbe2a966086a0a5cf /src/boost/libs/move/example | |
parent | Initial commit. (diff) | |
download | ceph-483eb2f56657e8e7f419ab1a4fab8dce9ade8609.tar.xz ceph-483eb2f56657e8e7f419ab1a4fab8dce9ade8609.zip |
Adding upstream version 14.2.21.upstream/14.2.21upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/move/example')
-rw-r--r-- | src/boost/libs/move/example/Jamfile.v2 | 31 | ||||
-rw-r--r-- | src/boost/libs/move/example/copymovable.hpp | 64 | ||||
-rw-r--r-- | src/boost/libs/move/example/doc_clone_ptr.cpp | 157 | ||||
-rw-r--r-- | src/boost/libs/move/example/doc_construct_forward.cpp | 109 | ||||
-rw-r--r-- | src/boost/libs/move/example/doc_file_descriptor.cpp | 92 | ||||
-rw-r--r-- | src/boost/libs/move/example/doc_how_works.cpp | 63 | ||||
-rw-r--r-- | src/boost/libs/move/example/doc_move_algorithms.cpp | 46 | ||||
-rw-r--r-- | src/boost/libs/move/example/doc_move_inserter.cpp | 52 | ||||
-rw-r--r-- | src/boost/libs/move/example/doc_move_iterator.cpp | 41 | ||||
-rw-r--r-- | src/boost/libs/move/example/doc_move_return.cpp | 70 | ||||
-rw-r--r-- | src/boost/libs/move/example/doc_template_assign.cpp | 98 | ||||
-rw-r--r-- | src/boost/libs/move/example/movable.hpp | 57 |
12 files changed, 880 insertions, 0 deletions
diff --git a/src/boost/libs/move/example/Jamfile.v2 b/src/boost/libs/move/example/Jamfile.v2 new file mode 100644 index 00000000..bc354e0f --- /dev/null +++ b/src/boost/libs/move/example/Jamfile.v2 @@ -0,0 +1,31 @@ +############################################################################## +## +## (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) +## +## +############################################################################## +# +import testing ; + +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 +; + diff --git a/src/boost/libs/move/example/copymovable.hpp b/src/boost/libs/move/example/copymovable.hpp new file mode 100644 index 00000000..173d420b --- /dev/null +++ b/src/boost/libs/move/example/copymovable.hpp @@ -0,0 +1,64 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (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 + +#include <boost/move/detail/config_begin.hpp> + +//[copy_movable_definition +//header file "copymovable.hpp" +#include <boost/move/core.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; } +}; + +//A copyable-only class +class copyable +{}; + +//A copyable-only class +class non_copy_movable +{ + public: + non_copy_movable(){} + private: + non_copy_movable(const non_copy_movable&); + non_copy_movable& operator=(const non_copy_movable&); +}; + +//] + +#include <boost/move/detail/config_end.hpp> + +#endif //BOOST_MOVE_TEST_COPYMOVABLE_HPP diff --git a/src/boost/libs/move/example/doc_clone_ptr.cpp b/src/boost/libs/move/example/doc_clone_ptr.cpp new file mode 100644 index 00000000..e0fa73c7 --- /dev/null +++ b/src/boost/libs/move/example/doc_clone_ptr.cpp @@ -0,0 +1,157 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (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/detail/config_begin.hpp> +#include <boost/move/utility_core.hpp> + +//[clone_ptr_base_derived +class Base +{ + BOOST_COPYABLE_AND_MOVABLE(Base) + + public: + Base(){} + + Base(const Base &/*x*/) {/**/} // Copy ctor + + 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); } + + virtual ~Base(){} +}; + +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_BASE(Base, x)), + mem_(boost::move(x.mem_)) { } + + Derived& operator=(BOOST_RV_REF(Derived) x) // Move assign + { + Base::operator=(BOOST_MOVE_BASE(Base, x)); + mem_ = boost::move(x.mem_); + return *this; + } + + Derived& operator=(BOOST_COPY_ASSIGN_REF(Derived) x) // Copy assign + { + Base::operator=(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; +} + +#include <boost/move/detail/config_end.hpp> diff --git a/src/boost/libs/move/example/doc_construct_forward.cpp b/src/boost/libs/move/example/doc_construct_forward.cpp new file mode 100644 index 00000000..388a97c8 --- /dev/null +++ b/src/boost/libs/move/example/doc_construct_forward.cpp @@ -0,0 +1,109 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (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. +// +////////////////////////////////////////////////////////////////////////////// + +#include <boost/move/detail/config_begin.hpp> + +//[construct_forward_example +#include <boost/move/utility_core.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; +} +//] + +#include <boost/move/detail/config_end.hpp> diff --git a/src/boost/libs/move/example/doc_file_descriptor.cpp b/src/boost/libs/move/example/doc_file_descriptor.cpp new file mode 100644 index 00000000..0ec39879 --- /dev/null +++ b/src/boost/libs/move/example/doc_file_descriptor.cpp @@ -0,0 +1,92 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2008-2012. +// 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/detail/config_begin.hpp> +#include <cassert> + +//[file_descriptor_def + +#include <boost/move/utility_core.hpp> +#include <stdexcept> + +class file_descriptor +{ + //<- + int operating_system_open_file(const char *) + { + return 1; + } + + void operating_system_close_file(int fd) + { (void)fd; assert(fd != 0); } + //-> + int os_descr_; + + private: + BOOST_MOVABLE_BUT_NOT_COPYABLE(file_descriptor) + + public: + explicit file_descriptor(const char *filename) //Constructor + : os_descr_(operating_system_open_file(filename)) + { 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/container/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::container::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::container::vector<file_descriptor> v2(v); + return 0; +} +//] + +#include <boost/move/detail/config_end.hpp> diff --git a/src/boost/libs/move/example/doc_how_works.cpp b/src/boost/libs/move/example/doc_how_works.cpp new file mode 100644 index 00000000..ef28be45 --- /dev/null +++ b/src/boost/libs/move/example/doc_how_works.cpp @@ -0,0 +1,63 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (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_CXX11_RVALUE_REFERENCES) + +int main() +{ + return 0; +} + +#else + +#include <boost/move/detail/config_begin.hpp> + +//[how_works_example +#include <boost/move/core.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; +} +//] + +#include <boost/move/detail/config_end.hpp> + +#endif diff --git a/src/boost/libs/move/example/doc_move_algorithms.cpp b/src/boost/libs/move/example/doc_move_algorithms.cpp new file mode 100644 index 00000000..6fe487aa --- /dev/null +++ b/src/boost/libs/move/example/doc_move_algorithms.cpp @@ -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. +// +////////////////////////////////////////////////////////////////////////////// + +#include <boost/move/detail/config_begin.hpp> + +//[move_algorithms_example +#include "movable.hpp" +#include <boost/move/algorithm.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; +} +//] + +#include <boost/move/detail/config_end.hpp> diff --git a/src/boost/libs/move/example/doc_move_inserter.cpp b/src/boost/libs/move/example/doc_move_inserter.cpp new file mode 100644 index 00000000..c7154124 --- /dev/null +++ b/src/boost/libs/move/example/doc_move_inserter.cpp @@ -0,0 +1,52 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (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/detail/config_begin.hpp> + +//[move_inserter_example +#include <boost/container/list.hpp> +#include "movable.hpp" +#include <cassert> +#include <algorithm> + +using namespace ::boost::container; + +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 insert into l2 containers + std::copy(l.begin(), l.end(), mit); + + //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; +} +//] + +#include <boost/move/detail/config_end.hpp> diff --git a/src/boost/libs/move/example/doc_move_iterator.cpp b/src/boost/libs/move/example/doc_move_iterator.cpp new file mode 100644 index 00000000..86d38939 --- /dev/null +++ b/src/boost/libs/move/example/doc_move_iterator.cpp @@ -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. +// +////////////////////////////////////////////////////////////////////////////// +#include <boost/move/detail/config_begin.hpp> +//[move_iterator_example +#include <boost/container/vector.hpp> +#include "movable.hpp" +#include <cassert> + +int main() +{ + using namespace ::boost::container; + + //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; +} +//] + +#include <boost/move/detail/config_end.hpp> diff --git a/src/boost/libs/move/example/doc_move_return.cpp b/src/boost/libs/move/example/doc_move_return.cpp new file mode 100644 index 00000000..0d5db0f9 --- /dev/null +++ b/src/boost/libs/move/example/doc_move_return.cpp @@ -0,0 +1,70 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (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. +// +////////////////////////////////////////////////////////////////////////////// + +#include <boost/move/detail/config_begin.hpp> + +//[move_return_example +#include "movable.hpp" +#include "copymovable.hpp" +#include <boost/move/core.hpp> + +template<class Type> +struct factory_functor +{ + typedef Type return_type; + + Type operator()() const + { Type t; return BOOST_MOVE_RET(Type, t); } +}; + +struct return_reference +{ + typedef non_copy_movable &return_type; + + non_copy_movable &operator()() const + { return ncm; } + + static non_copy_movable ncm; +}; + +non_copy_movable return_reference::ncm; + +//A wrapper that locks a mutex while the +//factory creates a new value. +//It must generically move the return value +//if possible both in C++03 and C++11 +template <class Factory> +typename Factory::return_type lock_wrapper(Factory f) +{ + typedef typename Factory::return_type return_type; + //LOCK(); + return_type r = f(); + //UNLOCK(); + + //In C++03: boost::move() if R is not a reference and + //has move emulation enabled. In C++11: just return r. + return BOOST_MOVE_RET(return_type, r); +} + +int main() +{ + movable m = lock_wrapper(factory_functor<movable> ()); + copy_movable cm = lock_wrapper(factory_functor<copy_movable>()); + copyable c = lock_wrapper(factory_functor<copyable> ()); + non_copy_movable &mr = lock_wrapper(return_reference ()); + //<- + (void)m; (void)cm; (void)c; (void)mr; + //-> + return 0; +} +//] + +#include <boost/move/detail/config_end.hpp> diff --git a/src/boost/libs/move/example/doc_template_assign.cpp b/src/boost/libs/move/example/doc_template_assign.cpp new file mode 100644 index 00000000..e1959a93 --- /dev/null +++ b/src/boost/libs/move/example/doc_template_assign.cpp @@ -0,0 +1,98 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (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. +// +////////////////////////////////////////////////////////////////////////////// + +#include <boost/move/detail/config_begin.hpp> +#include <boost/move/detail/meta_utils_core.hpp> + +#include <boost/move/move.hpp> + +//[template_assign_example_foo_bar + +class Foo +{ + BOOST_COPYABLE_AND_MOVABLE(Foo) + + public: + int i; + explicit Foo(int val) : i(val) {} + + Foo(BOOST_RV_REF(Foo) obj) : i(obj.i) {} + + Foo& operator=(BOOST_RV_REF(Foo) rhs) + { i = rhs.i; rhs.i = 0; return *this; } + + Foo& operator=(BOOST_COPY_ASSIGN_REF(Foo) rhs) + { i = rhs.i; return *this; } //(1) + + template<class U> //(*) TEMPLATED ASSIGNMENT, potential problem + //<- + #if 1 + typename ::boost::move_detail::disable_if_same<U, Foo, Foo&>::type + operator=(const U& rhs) + #else + //-> + Foo& operator=(const U& rhs) + //<- + #endif + //-> + { i = -rhs.i; return *this; } //(2) +}; +//] + +struct Bar +{ + int i; + explicit Bar(int val) : i(val) {} +}; + + +//<- +#ifdef NDEBUG +#undef NDEBUG +#endif +//-> +#include <cassert> + +int main() +{ +//[template_assign_example_main + Foo foo1(1); + //<- + assert(foo1.i == 1); + //-> + Foo foo2(2); + //<- + assert(foo2.i == 2); + Bar bar(3); + assert(bar.i == 3); + //-> + foo2 = foo1; // Calls (1) in C++11 but (2) in C++98 + //<- + assert(foo2.i == 1); + assert(foo1.i == 1); //Fails in C++98 unless workaround is applied + foo1 = bar; + assert(foo1.i == -3); + foo2 = boost::move(foo1); + assert(foo1.i == 0); + assert(foo2.i == -3); + //-> + const Foo foo5(5); + foo2 = foo5; // Calls (1) in C++11 but (2) in C++98 + //<- + assert(foo2.i == 5); //Fails in C++98 unless workaround is applied + assert(foo5.i == 5); + //-> +//] + return 0; +} + + +#include <boost/move/detail/config_end.hpp> diff --git a/src/boost/libs/move/example/movable.hpp b/src/boost/libs/move/example/movable.hpp new file mode 100644 index 00000000..7b1d990e --- /dev/null +++ b/src/boost/libs/move/example/movable.hpp @@ -0,0 +1,57 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (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 + +#include <boost/move/detail/config_begin.hpp> + +//[movable_definition +//header file "movable.hpp" +#include <boost/move/core.hpp> +#include <boost/move/traits.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_; } + + int value() const //Observer + { return value_; } +}; + +namespace boost{ + +template<> +struct has_nothrow_move<movable> +{ + static const bool value = true; +}; + +} //namespace boost{ +//] + +#include <boost/move/detail/config_end.hpp> + +#endif //BOOST_MOVE_TEST_MOVABLE_HPP |