Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-07-02 00:53:41

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     vb.reserve(2);
0077     B b;
0078     b.a.reset(new A(-2));
0079     B c;
0080     c.a.reset(new A(-7));
0081     B d;
0082     d.a.reset(new A(2));
0083     SECTION("push_back") {
0084       A::Guard ag;
0085       vb.push_back(b);
0086       REQUIRE(A::cla == 1);
0087 
0088       int cValue = c.a->i;
0089       vb.push_back(std::move(c));
0090       //some compilers will still cause a clone to be called and others won't
0091       REQUIRE((*vb.back().a).i == cValue);
0092       SECTION("assign to element") {
0093         A::Guard ag;
0094         vb[0] = d;
0095 
0096         REQUIRE(A::cla == 1);
0097         REQUIRE(vb[0].a->i == d.a->i);
0098         REQUIRE(vb[0].a->i == 2);
0099         SECTION("sort") {
0100           A::Guard ag;
0101           std::sort(vb.begin(), vb.end(), [](B const &rh, B const &lh) { return rh.a->i < lh.a->i; });
0102           REQUIRE((*vb[0].a).i == -7);
0103           REQUIRE(A::cla == 0);
0104           std::swap(b, d);
0105           REQUIRE(A::cla == 0);
0106         }
0107       }
0108     }
0109   }
0110 }