X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=ceph%2Fsrc%2Fboost%2Flibs%2Fmove%2Ftest%2Fcopy_elision_test.cpp;fp=ceph%2Fsrc%2Fboost%2Flibs%2Fmove%2Ftest%2Fcopy_elision_test.cpp;h=39123e1d5ead3a395fafaaf4825ac42126fed050;hb=7c673caec407dd16107e56e4b51a6d00f021315c;hp=0000000000000000000000000000000000000000;hpb=ec9abb229698c52dc3dff9591d4bd452d03cd004;p=ceph.git diff --git a/ceph/src/boost/libs/move/test/copy_elision_test.cpp b/ceph/src/boost/libs/move/test/copy_elision_test.cpp new file mode 100644 index 000000000..39123e1d5 --- /dev/null +++ b/ceph/src/boost/libs/move/test/copy_elision_test.cpp @@ -0,0 +1,177 @@ +// Copyright David Abrahams 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) + +#include +#include +#include + +#ifdef NO_MOVE +# undef BOOST_COPY_ASSIGN_REF +# define BOOST_COPY_ASSIGN_REF(X) X const& +# undef BOOST_COPYABLE_AND_MOVABLE +# define BOOST_COPYABLE_AND_MOVABLE(X) +# define MOVE(x) (x) +#else +#include +# define MOVE(x) boost::move(x) +#endif + +struct X +{ + X() : id(instances++) + { + std::cout << "X" << id << ": construct\n"; + } + + X(X const& rhs) : id(instances++) + { + std::cout << "X" << id << ": <- " << "X" << rhs.id << ": **copy**\n"; + ++copies; + } + + // This particular test doesn't exercise assignment, but for + // completeness: + X& operator=(BOOST_COPY_ASSIGN_REF(X) rhs) + { + std::cout << "X" << id << ": <- " << "X" << rhs.id << ": assign\n"; + return *this; + } + +#ifndef NO_MOVE + X& operator=(BOOST_RV_REF(X) rhs) + { + std::cout << "X" << id << ": <- " << "X" << rhs.id << ": move assign\n"; + return *this; + } + + X(BOOST_RV_REF(X) rhs) : id(instances++) + { + std::cout << "X" << id << ": <- " << "X" << rhs.id << ": ..move construct..\n"; + ++copies; + } +#endif + + ~X() { std::cout << "X" << id << ": destroy\n"; } + + unsigned id; + + static unsigned copies; + static unsigned instances; + + BOOST_COPYABLE_AND_MOVABLE(X) +}; + +unsigned X::copies = 0; +unsigned X::instances = 0; + +#define CHECK_COPIES( stmt, min, max, comment ) \ +{ \ + unsigned const old_copies = X::copies; \ + \ + std::cout << "\n" comment "\n" #stmt "\n===========\n"; \ + { \ + stmt; \ + } \ + unsigned const n = X::copies - old_copies; \ + volatile unsigned const minv(min), maxv(max); \ + BOOST_TEST(n <= maxv); \ + if (n > maxv) \ + std::cout << "*** max is too low or compiler is buggy ***\n"; \ + BOOST_TEST(n >= minv); \ + if (n < minv) \ + std::cout << "*** min is too high or compiler is buggy ***\n"; \ + \ + std::cout << "-----------\n" \ + << n << "/" << max \ + << " possible copies/moves made\n" \ + << max - n << "/" << max - min \ + << " possible elisions performed\n\n"; \ + \ + if (n > minv) \ + std::cout << "*** " << n - min \ + << " possible elisions missed! ***\n"; \ +} + +struct trace +{ + trace(char const* name) + : m_name(name) + { + std::cout << "->: " << m_name << "\n"; + } + + ~trace() + { + std::cout << "<-: " << m_name << "\n"; + } + + char const* m_name; +}; + +void sink(X) +{ + trace t("sink"); +} + +X nrvo_source() +{ + trace t("nrvo_source"); + X a; + return a; +} + +X urvo_source() +{ + trace t("urvo_source"); + return X(); +} + +X identity(X a) +{ + trace t("identity"); + return a; +} + +X lvalue_; +X& lvalue() +{ + return lvalue_; +} +typedef X rvalue; + +X ternary( bool y ) +{ + X a, b; + return MOVE(y?a:b); +} + +int main(int argc, char* argv[]) +{ + (void)argv; + // Double parens prevent "most vexing parse" + CHECK_COPIES( X a(( lvalue() )), 1U, 1U, "Direct initialization from lvalue"); + CHECK_COPIES( X a(( rvalue() )), 0U, 1U, "Direct initialization from rvalue"); + + CHECK_COPIES( X a = lvalue(), 1U, 1U, "Copy initialization from lvalue" ); + CHECK_COPIES( X a = rvalue(), 0U, 1U, "Copy initialization from rvalue" ); + + CHECK_COPIES( sink( lvalue() ), 1U, 1U, "Pass lvalue by value" ); + CHECK_COPIES( sink( rvalue() ), 0U, 1U, "Pass rvalue by value" ); + + CHECK_COPIES( nrvo_source(), 0U, 1U, "Named return value optimization (NRVO)" ); + CHECK_COPIES( urvo_source(), 0U, 1U, "Unnamed return value optimization (URVO)" ); + + // Just to prove these things compose properly + CHECK_COPIES( X a(urvo_source()), 0U, 2U, "Return value used as ctor arg" ); + + // Expect to miss one possible elision here + CHECK_COPIES( identity( rvalue() ), 0U, 2U, "Return rvalue passed by value" ); + + // Expect to miss an elision in at least one of the following lines + CHECK_COPIES( X a = ternary( argc == 1000 ), 0U, 2U, "Return result of ternary operation" ); + CHECK_COPIES( X a = ternary( argc != 1000 ), 0U, 2U, "Return result of ternary operation again" ); + return boost::report_errors(); +} + +#include