Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:03:56

0001 #include <algorithm>
0002 #include <cassert>
0003 #include <memory>
0004 #include "catch.hpp"
0005 
0006 #include "DataFormats/Common/interface/OwnVector.h"
0007 #include "FWCore/Utilities/interface/propagate_const.h"
0008 
0009 namespace ownvector_test {
0010   struct Base {
0011     virtual ~Base();
0012     virtual Base* clone() const = 0;
0013   };
0014 
0015   Base::~Base() {}
0016 
0017   struct Derived : Base {
0018     explicit Derived(int n);
0019     Derived(Derived const& other);
0020     Derived& operator=(Derived const& other);
0021     virtual ~Derived();
0022     void swap(Derived& other);
0023     virtual Derived* clone() const;
0024 
0025     edm::propagate_const<int*> pointer;
0026   };
0027 
0028   void Derived::swap(Derived& other) { std::swap(pointer, other.pointer); }
0029   Derived::Derived(int n) : pointer(new int(n)) {}
0030 
0031   Derived::Derived(Derived const& other) : pointer(new int(*other.pointer)) {}
0032 
0033   Derived& Derived::operator=(Derived const& other) {
0034     Derived temp(other);
0035     swap(temp);
0036     return *this;
0037   }
0038 
0039   Derived::~Derived() { delete pointer.get(); }
0040 
0041   Derived* Derived::clone() const { return new Derived(*this); }
0042 
0043   void swap(Derived& a, Derived& b) { a.swap(b); }
0044 
0045   void do_assign(edm::OwnVector<Base>& iLHS, edm::OwnVector<Base>& iRHS) { iLHS = iRHS; }
0046 
0047 }  // namespace ownvector_test
0048 
0049 using namespace ownvector_test;
0050 
0051 TEST_CASE("test OwnVector", "[OwnVector]") {
0052   SECTION("copy_good_vec") {
0053     // v1 is perfectly fine...
0054     edm::OwnVector<Base> v1;
0055     Base* p = new Derived(100);
0056     v1.push_back(p);
0057     //v1.push_back(new Derived(100));
0058 
0059     // But what if we copy him?
0060     edm::OwnVector<Base> v2(v1);
0061   }
0062 
0063   SECTION("assign_to_other") {
0064     edm::OwnVector<Base> v1;
0065     Base* p = new Derived(100);
0066     v1.push_back(p);
0067 
0068     edm::OwnVector<Base> v2;
0069     v2 = v1;
0070   }
0071 
0072   SECTION("assign_to_self") {
0073     // Self-assignment happens, often by accident...
0074     edm::OwnVector<Base> v1;
0075     v1.push_back(new Derived(100));
0076     auto& v2 = v1;
0077     do_assign(v1, v2);
0078   }
0079 
0080   SECTION("pop_one") {
0081     edm::OwnVector<Base> v1;
0082     v1.push_back(new Derived(100));
0083     v1.pop_back();
0084   }
0085 
0086   SECTION("back_with_null_pointer") {
0087     edm::OwnVector<Base> v;
0088     Base* p = 0;
0089     v.push_back(p);
0090     REQUIRE_THROWS_AS(v.back(), edm::Exception);
0091   }
0092 
0093   SECTION("take_an_rvalue") {
0094     edm::OwnVector<Base> v;
0095     v.push_back(new Derived(101));
0096     Derived d(102);
0097     v.push_back(d.clone());
0098   }
0099 
0100   SECTION("take_an_lvalue") {
0101     edm::OwnVector<Base> v1;
0102     Base* p = new Derived(100);
0103     v1.push_back(p);
0104 
0105     REQUIRE(p == nullptr);
0106   }
0107 
0108   SECTION("take_an_auto_ptr") {
0109     edm::OwnVector<Base> v1;
0110     std::unique_ptr<Base> p = std::make_unique<Derived>(100);
0111     v1.push_back(std::move(p));
0112     REQUIRE(p.get() == nullptr);
0113   }
0114 
0115   SECTION("set_at_index") {
0116     edm::OwnVector<Base> v1;
0117     Base* p = new Derived(100);
0118     Base* backup = p;
0119     v1.push_back(p);
0120     REQUIRE(p == nullptr);
0121     REQUIRE(&v1[0] == backup);
0122     Base* p2 = new Derived(101);
0123     Base* backup2 = p2;
0124     REQUIRE(backup2 != backup);
0125     v1.set(0, p2);
0126     REQUIRE(p2 == nullptr);
0127     REQUIRE(&v1[0] == backup2);
0128   }
0129 
0130   SECTION("insert_with_iter") {
0131     edm::OwnVector<Base> v1;
0132     Base *p[3], *backup[3];
0133     for (int i = 0; i < 3; ++i) {
0134       backup[i] = p[i] = new Derived(100 + i);
0135     }
0136     v1.push_back(p[0]);
0137     v1.push_back(p[2]);
0138     v1.insert(v1.begin() + 1, p[1]);
0139     REQUIRE(p[0] == nullptr);
0140     REQUIRE(p[1] == nullptr);
0141     REQUIRE(p[2] == nullptr);
0142     REQUIRE(&v1[0] == backup[0]);
0143     REQUIRE(&v1[1] == backup[1]);
0144     REQUIRE(&v1[2] == backup[2]);
0145   }
0146   SECTION("no crash") {
0147     edm::OwnVector<Base> vec;
0148     vec.push_back(new Derived(100));
0149     edm::OwnVector<Base>* p = new edm::OwnVector<Base>;
0150     p->push_back(new Derived(2));
0151     delete p;
0152   }
0153 }