diff options
Diffstat (limited to 'libs/move')
-rw-r--r-- | libs/move/doc/move.qbk | 33 | ||||
-rw-r--r-- | libs/move/example/doc_clone_ptr.cpp | 8 | ||||
-rw-r--r-- | libs/move/proj/vc7ide/Move.sln | 13 | ||||
-rw-r--r-- | libs/move/proj/vc7ide/adl_move_swap.vcproj | 134 | ||||
-rw-r--r-- | libs/move/test/adl_move_swap.cpp | 169 | ||||
-rw-r--r-- | libs/move/test/back_move_inserter.cpp | 3 | ||||
-rw-r--r-- | libs/move/test/move_iterator.cpp | 25 | ||||
-rw-r--r-- | libs/move/test/unique_ptr_modifiers.cpp | 3 |
8 files changed, 357 insertions, 31 deletions
diff --git a/libs/move/doc/move.qbk b/libs/move/doc/move.qbk index dbd7d11a8..729e92a43 100644 --- a/libs/move/doc/move.qbk +++ b/libs/move/doc/move.qbk @@ -532,19 +532,26 @@ care to achieve portable and efficient code when using the library with C++03 co [section:emulation_limitations_base Initializing base classes] When initializing base classes in move constructors, users must -cast the reference to a base class reference before moving it. Example: +cast the reference to a base class reference before moving it or just +use `BOOST_MOVE_BASE`. Example: [c++] - //Portable and efficient Derived(BOOST_RV_REF(Derived) x) // Move ctor - : Base(boost::move(static_cast<Base&>(x))), - mem_(boost::move(x.mem_)) { } + : Base(boost::move(static_cast<Base&>(x))) + //... +or + +[c++] + + Derived(BOOST_RV_REF(Derived) x) // Move ctor + : Base(BOOST_MOVE_BASE(Base, x)) + //... If casting is not performed the emulation will not move construct -the base class, because no conversion is available from `BOOST_RV_REF(Derived)` -to `BOOST_RV_REF(Base)`. Without the cast we might obtain a compilation +the base class, because no conversion is available from `BOOST_RV_REF(Derived)` to +`BOOST_RV_REF(Base)`. Without the cast or `BOOST_MOVE_BASE` we might obtain a compilation error (for non-copyable types) or a less-efficient move constructor (for copyable types): [c++] @@ -552,8 +559,8 @@ error (for non-copyable types) or a less-efficient move constructor (for copyabl //If Derived is copyable, then Base is copy-constructed. //If not, a compilation error is issued Derived(BOOST_RV_REF(Derived) x) // Move ctor - : Base(boost::move(x)), - mem_(boost::move(x.mem_)) { } + : Base(boost::move(x)) + //... [endsect] @@ -755,6 +762,16 @@ Many thanks to all boosters that have tested, reviewed and improved the library. [section:release_notes Release Notes] +[section:release_notes_boost_1_58_00 Boost 1.58 Release] + +* Added [macroref BOOST_MOVE_BASE BOOST_MOVE_BASE] utility. +* Added [funcref boost::adl_move_swap adl_move_swap] utility. +* Reduced dependencies on other Boost libraries to make the library a bit more lightweight. +* Fixed bugs: + * [@https://svn.boost.org/trac/boost/ticket/11044 Trac #11044: ['"boost::rv inherits off union, when such passed as template argument"]]. + +[endsect] + [section:release_notes_boost_1_57_00 Boost 1.57 Release] * Added `unique_ptr` smart pointer. Thanks to Howard Hinnant for his excellent unique_ptr emulation code and testsuite. diff --git a/libs/move/example/doc_clone_ptr.cpp b/libs/move/example/doc_clone_ptr.cpp index 8842e38fe..e0fa73c76 100644 --- a/libs/move/example/doc_clone_ptr.cpp +++ b/libs/move/example/doc_clone_ptr.cpp @@ -64,19 +64,19 @@ class Derived : public Base // Compiler-generated copy constructor... Derived(BOOST_RV_REF(Derived) x) // Move ctor - : Base(boost::move(static_cast<Base&>(x))), + : Base(BOOST_MOVE_BASE(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_); + 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=(static_cast<const Base&>(x)); + Base::operator=(x); mem_ = x.mem_; return *this; } diff --git a/libs/move/proj/vc7ide/Move.sln b/libs/move/proj/vc7ide/Move.sln index c12681b7e..4b230a8a5 100644 --- a/libs/move/proj/vc7ide/Move.sln +++ b/libs/move/proj/vc7ide/Move.sln @@ -103,6 +103,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unique_ptr_types_test", "un ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "adl_move_swap", "adl_move_swap.vcproj", "{CD2617A8-79EB-6172-2CE4-26617AA3AC93}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject Global GlobalSection(SolutionConfiguration) = preSolution Debug = Debug @@ -215,21 +219,30 @@ Global {C57C28A3-4FE0-6208-BF87-B2B61D3A7675}.Debug.Build.0 = Debug|Win32 {C57C28A3-4FE0-6208-BF87-B2B61D3A7675}.Release.ActiveCfg = Release|Win32 {C57C28A3-4FE0-6208-BF87-B2B61D3A7675}.Release.Build.0 = Release|Win32 + {CD2617A8-79EB-6172-2CE4-26617AA3AC93}.Debug.ActiveCfg = Debug|Win32 + {CD2617A8-79EB-6172-2CE4-26617AA3AC93}.Debug.Build.0 = Debug|Win32 + {CD2617A8-79EB-6172-2CE4-26617AA3AC93}.Release.ActiveCfg = Release|Win32 + {CD2617A8-79EB-6172-2CE4-26617AA3AC93}.Release.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionItems) = postSolution + ..\..\..\..\boost\move\adl_move_swap.hpp = ..\..\..\..\boost\move\adl_move_swap.hpp ..\..\..\..\boost\move\algorithm.hpp = ..\..\..\..\boost\move\algorithm.hpp ..\..\..\..\boost\move\detail\config_begin.hpp = ..\..\..\..\boost\move\detail\config_begin.hpp ..\..\..\..\boost\move\detail\config_end.hpp = ..\..\..\..\boost\move\detail\config_end.hpp ..\..\..\..\boost\move\core.hpp = ..\..\..\..\boost\move\core.hpp ..\..\..\..\boost\move\default_delete.hpp = ..\..\..\..\boost\move\default_delete.hpp + ..\..\..\..\boost\move\detail\fwd_macros.hpp = ..\..\..\..\boost\move\detail\fwd_macros.hpp ..\..\..\..\boost\move\iterator.hpp = ..\..\..\..\boost\move\iterator.hpp + ..\..\..\..\boost\move\detail\iterator_traits.hpp = ..\..\..\..\boost\move\detail\iterator_traits.hpp ..\..\doc\Jamfile.v2 = ..\..\doc\Jamfile.v2 ..\..\..\..\boost\move\make_unique.hpp = ..\..\..\..\boost\move\make_unique.hpp ..\..\..\..\boost\move\detail\meta_utils.hpp = ..\..\..\..\boost\move\detail\meta_utils.hpp + ..\..\..\..\boost\move\detail\meta_utils_core.hpp = ..\..\..\..\boost\move\detail\meta_utils_core.hpp ..\..\..\..\boost\move\move.hpp = ..\..\..\..\boost\move\move.hpp ..\..\doc\move.qbk = ..\..\doc\move.qbk ..\..\..\..\boost\move\detail\move_helpers.hpp = ..\..\..\..\boost\move\detail\move_helpers.hpp ..\..\..\..\boost\move\traits.hpp = ..\..\..\..\boost\move\traits.hpp + ..\..\..\..\boost\move\detail\type_traits.hpp = ..\..\..\..\boost\move\detail\type_traits.hpp ..\..\..\..\boost\move\unique_ptr.hpp = ..\..\..\..\boost\move\unique_ptr.hpp ..\..\..\..\boost\move\detail\unique_ptr_meta_utils.hpp = ..\..\..\..\boost\move\detail\unique_ptr_meta_utils.hpp ..\..\test\unique_ptr_test_utils_beg.hpp = ..\..\test\unique_ptr_test_utils_beg.hpp diff --git a/libs/move/proj/vc7ide/adl_move_swap.vcproj b/libs/move/proj/vc7ide/adl_move_swap.vcproj new file mode 100644 index 000000000..4c5749132 --- /dev/null +++ b/libs/move/proj/vc7ide/adl_move_swap.vcproj @@ -0,0 +1,134 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="7.10" + Name="adl_move_swap" + ProjectGUID="{CD2617A8-79EB-6172-2CE4-26617AA3AC93}" + Keyword="Win32Proj"> + <Platforms> + <Platform + Name="Win32"/> + </Platforms> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="../../Bin/Win32/Debug" + IntermediateDirectory="Debug/move_adl_move_swap" + ConfigurationType="1" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../../.." + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB" + MinimalRebuild="TRUE" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + DisableLanguageExtensions="FALSE" + TreatWChar_tAsBuiltInType="TRUE" + ForceConformanceInForLoopScope="TRUE" + UsePrecompiledHeader="0" + WarningLevel="4" + Detect64BitPortabilityProblems="TRUE" + DebugInformationFormat="3"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib" + OutputFile="$(OutDir)/move_iterator_test_d.exe" + LinkIncremental="1" + AdditionalLibraryDirectories="../../../../stage/lib" + GenerateDebugInformation="TRUE" + ProgramDatabaseFile="$(OutDir)/move_adl_move_swap.pdb" + SubSystem="1" + TargetMachine="1" + FixedBaseAddress="1"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCWebDeploymentTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="../../Bin/Win32/Release" + IntermediateDirectory="Release/move_adl_move_swap" + ConfigurationType="1" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="../../../.." + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB" + RuntimeLibrary="2" + TreatWChar_tAsBuiltInType="TRUE" + ForceConformanceInForLoopScope="FALSE" + UsePrecompiledHeader="0" + WarningLevel="4" + Detect64BitPortabilityProblems="TRUE" + DebugInformationFormat="0"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="winmm.lib" + OutputFile="$(OutDir)/move_adl_move_swap.exe" + LinkIncremental="1" + AdditionalLibraryDirectories="../../../../stage/lib" + GenerateDebugInformation="TRUE" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCWebDeploymentTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{163D8753-4026-0A65-5C56-2BA532AD7FEF}"> + <File + RelativePath="..\..\test\adl_move_swap.cpp"> + </File> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/libs/move/test/adl_move_swap.cpp b/libs/move/test/adl_move_swap.cpp new file mode 100644 index 000000000..9aeae4374 --- /dev/null +++ b/libs/move/test/adl_move_swap.cpp @@ -0,0 +1,169 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (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/adl_move_swap.hpp> +#include <boost/move/core.hpp> +#include <boost/core/lightweight_test.hpp> + +class swap_stats +{ + public: + static void reset_stats() + { + member_swap_calls = 0; + friend_swap_calls = 0; + move_cnstor_calls = 0; + move_assign_calls = 0; + copy_cnstor_calls = 0; + copy_assign_calls = 0; + } + + static unsigned int member_swap_calls; + static unsigned int friend_swap_calls; + static unsigned int move_cnstor_calls; + static unsigned int move_assign_calls; + static unsigned int copy_cnstor_calls; + static unsigned int copy_assign_calls; +}; + +unsigned int swap_stats::member_swap_calls = 0; +unsigned int swap_stats::friend_swap_calls = 0; +unsigned int swap_stats::move_cnstor_calls = 0; +unsigned int swap_stats::move_assign_calls = 0; +unsigned int swap_stats::copy_cnstor_calls = 0; +unsigned int swap_stats::copy_assign_calls = 0; + +class movable : public swap_stats +{ + BOOST_MOVABLE_BUT_NOT_COPYABLE(movable) + public: + movable() {} + movable(BOOST_RV_REF(movable)) { ++move_cnstor_calls; } + movable & operator=(BOOST_RV_REF(movable)){ ++move_assign_calls; return *this; } + friend void swap(movable &, movable &) { ++friend_swap_calls; } +}; + +class movable_swap_member : public swap_stats +{ + BOOST_MOVABLE_BUT_NOT_COPYABLE(movable_swap_member) + public: + movable_swap_member() {} + movable_swap_member(BOOST_RV_REF(movable_swap_member)) { ++move_cnstor_calls; } + movable_swap_member & operator=(BOOST_RV_REF(movable_swap_member)){ ++move_assign_calls; return *this; } + void swap(movable_swap_member &) { ++member_swap_calls; } + friend void swap(movable_swap_member &, movable_swap_member &) { ++friend_swap_calls; } +}; + +class copyable : public swap_stats +{ + public: + copyable() {} + copyable(const copyable &) { ++copy_cnstor_calls; } + copyable & operator=(const copyable&) { ++copy_assign_calls; return *this; } + void swap(copyable &) { ++member_swap_calls; } + friend void swap(copyable &, copyable &) { ++friend_swap_calls; } +}; + +class no_swap : public swap_stats +{ + private: unsigned m_state; + public: + explicit no_swap(unsigned i): m_state(i){} + no_swap(const no_swap &x) { m_state = x.m_state; ++copy_cnstor_calls; } + no_swap & operator=(const no_swap& x) { m_state = x.m_state; ++copy_assign_calls; return *this; } + void swap(no_swap &) { ++member_swap_calls; } + friend bool operator==(const no_swap &x, const no_swap &y) { return x.m_state == y.m_state; } + friend bool operator!=(const no_swap &x, const no_swap &y) { return !(x==y); } +}; + + +int main() +{ + { //movable + movable x, y; + swap_stats::reset_stats(); + ::boost::adl_move_swap(x, y); + #if defined(BOOST_NO_RVALUE_REFERENCES) + //In non rvalue reference compilers, + //movable classes with no swap() member uses + //boost::move() to implement swap. + BOOST_TEST(swap_stats::friend_swap_calls == 0); + BOOST_TEST(swap_stats::member_swap_calls == 0); + BOOST_TEST(swap_stats::member_swap_calls == 0); + BOOST_TEST(swap_stats::move_cnstor_calls == 1); + BOOST_TEST(swap_stats::move_assign_calls == 2); + BOOST_TEST(swap_stats::copy_cnstor_calls == 0); + BOOST_TEST(swap_stats::copy_assign_calls == 0); + #else + //In compilers with rvalue references, this should call friend swap via ADL + BOOST_TEST(swap_stats::friend_swap_calls == 1); + BOOST_TEST(swap_stats::member_swap_calls == 0); + BOOST_TEST(swap_stats::member_swap_calls == 0); + BOOST_TEST(swap_stats::move_cnstor_calls == 0); + BOOST_TEST(swap_stats::move_assign_calls == 0); + BOOST_TEST(swap_stats::copy_cnstor_calls == 0); + BOOST_TEST(swap_stats::copy_assign_calls == 0); + #endif + } + { //movable_swap_member + movable_swap_member x, y; + swap_stats::reset_stats(); + ::boost::adl_move_swap(x, y); + #if defined(BOOST_NO_RVALUE_REFERENCES) + //In non rvalue reference compilers, + //movable classes with no swap() member uses + //boost::move() to implement swap. + BOOST_TEST(swap_stats::friend_swap_calls == 0); + BOOST_TEST(swap_stats::member_swap_calls == 1); + BOOST_TEST(swap_stats::move_cnstor_calls == 0); + BOOST_TEST(swap_stats::move_assign_calls == 0); + BOOST_TEST(swap_stats::copy_cnstor_calls == 0); + BOOST_TEST(swap_stats::copy_assign_calls == 0); + #else + //In compilers with rvalue references, this should call friend swap via ADL + BOOST_TEST(swap_stats::friend_swap_calls == 1); + BOOST_TEST(swap_stats::member_swap_calls == 0); + BOOST_TEST(swap_stats::move_cnstor_calls == 0); + BOOST_TEST(swap_stats::move_assign_calls == 0); + BOOST_TEST(swap_stats::copy_cnstor_calls == 0); + BOOST_TEST(swap_stats::copy_assign_calls == 0); + #endif + } + { //copyable + copyable x, y; + swap_stats::reset_stats(); + ::boost::adl_move_swap(x, y); + //This should call friend swap via ADL + BOOST_TEST(swap_stats::friend_swap_calls == 1); + BOOST_TEST(swap_stats::member_swap_calls == 0); + BOOST_TEST(swap_stats::move_cnstor_calls == 0); + BOOST_TEST(swap_stats::move_assign_calls == 0); + BOOST_TEST(swap_stats::copy_cnstor_calls == 0); + BOOST_TEST(swap_stats::copy_assign_calls == 0); + } + { //no_swap + no_swap x(1), y(2), x_back(x), y_back(y); + swap_stats::reset_stats(); + ::boost::adl_move_swap(x, y); + //This should call std::swap which uses copies + BOOST_TEST(swap_stats::friend_swap_calls == 0); + BOOST_TEST(swap_stats::member_swap_calls == 0); + BOOST_TEST(swap_stats::move_cnstor_calls == 0); + BOOST_TEST(swap_stats::move_assign_calls == 0); + BOOST_TEST(swap_stats::copy_cnstor_calls == 1); + BOOST_TEST(swap_stats::copy_assign_calls == 2); + BOOST_TEST(x == y_back); + BOOST_TEST(y == x_back); + BOOST_TEST(x != y); + } + return ::boost::report_errors(); +} +#include <boost/move/detail/config_end.hpp> diff --git a/libs/move/test/back_move_inserter.cpp b/libs/move/test/back_move_inserter.cpp index eeddd6b50..6fc4829c8 100644 --- a/libs/move/test/back_move_inserter.cpp +++ b/libs/move/test/back_move_inserter.cpp @@ -9,7 +9,10 @@ // ////////////////////////////////////////////////////////////////////////////// #include <boost/move/detail/config_begin.hpp> +// move +#include <boost/move/algorithm.hpp> #include <boost/move/iterator.hpp> +// container #include <boost/container/deque.hpp> #include <boost/container/list.hpp> #include <boost/container/stable_vector.hpp> diff --git a/libs/move/test/move_iterator.cpp b/libs/move/test/move_iterator.cpp index 37c39f3bc..fded99a8b 100644 --- a/libs/move/test/move_iterator.cpp +++ b/libs/move/test/move_iterator.cpp @@ -11,6 +11,7 @@ #include <boost/move/detail/config_begin.hpp> #include <boost/move/iterator.hpp> #include <boost/container/vector.hpp> +#include <boost/core/lightweight_test.hpp> #include "../example/movable.hpp" int main() @@ -20,36 +21,24 @@ int main() bc::vector<movable> v(10); //Test default constructed value - if(v[0].moved()){ - return 1; - } + BOOST_TEST(!v[0].moved()); //Move values bc::vector<movable> v2 (boost::make_move_iterator(v.begin()), boost::make_move_iterator(v.end())); //Test values have been moved - if(!v[0].moved()){ - return 1; - } - - if(v2.size() != 10){ - return 1; - } + BOOST_TEST(v[0].moved()); + BOOST_TEST(v2.size() == 10); //Move again v.assign(boost::make_move_iterator(v2.begin()), boost::make_move_iterator(v2.end())); //Test values have been moved - if(!v2[0].moved()){ - return 1; - } - - if(v[0].moved()){ - return 1; - } + BOOST_TEST(v2[0].moved()); + BOOST_TEST(!v[0].moved()); - return 0; + return ::boost::report_errors(); } #include <boost/move/detail/config_end.hpp> diff --git a/libs/move/test/unique_ptr_modifiers.cpp b/libs/move/test/unique_ptr_modifiers.cpp index b67d4f558..3de952d20 100644 --- a/libs/move/test/unique_ptr_modifiers.cpp +++ b/libs/move/test/unique_ptr_modifiers.cpp @@ -13,6 +13,7 @@ #include <boost/move/utility_core.hpp> #include <boost/move/unique_ptr.hpp> #include <boost/static_assert.hpp> +#include <boost/move/adl_move_swap.hpp> #include <boost/core/lightweight_test.hpp> ////////////////////////////////////////////// @@ -284,7 +285,7 @@ void test() BOOST_TEST(s2.get() == p2); BOOST_TEST(*s2 == A(2)); BOOST_TEST(s2.get_deleter().state() == 2); - swap(s1, s2); + boost::adl_move_swap(s1, s2); BOOST_TEST(s1.get() == p2); BOOST_TEST(*s1 == A(2)); BOOST_TEST(s1.get_deleter().state() == 2); |