Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-10-25 09:48:02

0001 #include "catch.hpp"
0002 #include "FWCore/Utilities/interface/clone_ptr.h"
0003 #include <vector>
0004 
0005 namespace {
0006 
0007   struct A {
0008     A() {}
0009     A(int j) : i(j) {}
0010 
0011     A *clone() const {
0012       cla++; /*std::cout<< "c A " << i << std::endl;*/
0013       return new A(*this);
0014     }
0015 
0016     int i = 3;
0017     static int cla;
0018     struct Guard {
0019       Guard() : old_(A::cla) { A::cla = 0; }
0020       ~Guard() { A::cla = old_; }
0021       int old_;
0022     };
0023   };
0024   int A::cla = 0;
0025 
0026   struct B {
0027     B() {}
0028     B(B const &b) : a(b.a) {}
0029     B(B &&b) noexcept : a(std::move(b.a)) {}
0030 
0031     B &operator=(B const &b) {
0032       a = b.a;
0033       return *this;
0034     }
0035     B &operator=(B &&b) noexcept {
0036       a = std::move(b.a);
0037       return *this;
0038     }
0039 
0040     extstd::clone_ptr<A> a;
0041   };
0042 
0043 }  // namespace
0044 
0045 TEST_CASE("Test clone_ptr", "[clone_ptr]") {
0046   SECTION("standalone") {
0047     A::Guard ag;
0048     B b;
0049     b.a.reset(new A(2));
0050 
0051     REQUIRE(A::cla == 0);
0052     B c = b;
0053     REQUIRE(A::cla == 1);
0054     B d = b;
0055     REQUIRE(A::cla == 2);
0056 
0057     SECTION("separate values") {
0058       b.a.reset(new A(-2));
0059       REQUIRE(c.a->i == 2);
0060       REQUIRE(b.a->i == -2);
0061       SECTION("operator=") {
0062         A::Guard ag;
0063         c = b;
0064         REQUIRE(A::cla == 1);
0065 
0066         REQUIRE(c.a->i == -2);
0067         c.a.reset(new A(-7));
0068         REQUIRE(c.a->i == -7);
0069         REQUIRE(A::cla == 1);
0070       }
0071     }
0072   }
0073   SECTION("in vector") {
0074     A::Guard ag;
0075     std::vector<B> vb(1);
0076     B b;
0077     b.a.reset(new A(-2));
0078     B c;
0079     c.a.reset(new A(-7));
0080     B d;
0081     d.a.reset(new A(2));
0082     SECTION("push_back") {
0083       A::Guard ag;
0084       vb.push_back(b);
0085       REQUIRE(A::cla == 1);
0086 
0087       int cValue = c.a->i;
0088       vb.push_back(std::move(c));
0089       //some compilers will still cause a clone to be called and others won't
0090       REQUIRE((*vb.back().a).i == cValue);
0091       SECTION("assign to element") {
0092         A::Guard ag;
0093         vb[0] = d;
0094 
0095         REQUIRE(A::cla == 1);
0096         REQUIRE(vb[0].a->i == d.a->i);
0097         REQUIRE(vb[0].a->i == 2);
0098         SECTION("sort") {
0099           A::Guard ag;
0100           std::sort(vb.begin(), vb.end(), [](B const &rh, B const &lh) { return rh.a->i < lh.a->i; });
0101           REQUIRE((*vb[0].a).i == -7);
0102           REQUIRE(A::cla == 0);
0103           std::swap(b, d);
0104           REQUIRE(A::cla == 0);
0105         }
0106       }
0107     }
0108   }
0109 }