Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-03-17 10:49:30

0001 #include <algorithm>
0002 #include <cassert>
0003 #include <memory>
0004 
0005 #include "DataFormats/Common/interface/OwnVector.h"
0006 #include "FWCore/Utilities/interface/propagate_const.h"
0007 
0008 namespace ownvector_test {
0009   struct Base {
0010     virtual ~Base();
0011     virtual Base* clone() const = 0;
0012   };
0013 
0014   Base::~Base() {}
0015 
0016   struct Derived : Base {
0017     explicit Derived(int n);
0018     Derived(Derived const& other);
0019     Derived& operator=(Derived const& other);
0020     virtual ~Derived();
0021     void swap(Derived& other);
0022     virtual Derived* clone() const;
0023 
0024     edm::propagate_const<int*> pointer;
0025   };
0026 
0027   void Derived::swap(Derived& other) { std::swap(pointer, other.pointer); }
0028   Derived::Derived(int n) : pointer(new int(n)) {}
0029 
0030   Derived::Derived(Derived const& other) : pointer(new int(*other.pointer)) {}
0031 
0032   Derived& Derived::operator=(Derived const& other) {
0033     Derived temp(other);
0034     swap(temp);
0035     return *this;
0036   }
0037 
0038   Derived::~Derived() { delete pointer.get(); }
0039 
0040   Derived* Derived::clone() const { return new Derived(*this); }
0041 
0042   void swap(Derived& a, Derived& b) { a.swap(b); }
0043 
0044 }  // namespace ownvector_test
0045 
0046 using namespace ownvector_test;
0047 
0048 namespace {
0049 
0050   /*
0051 void same_guy_twice()
0052 {
0053   edm::OwnVector<Base> vec;
0054   Base* p = new Derived(1);
0055 
0056   vec.push_back(p);
0057   vec.push_back(p);
0058 }
0059 
0060 void two_different_owners()
0061 {
0062   edm::OwnVector<Base> v1,v2;
0063   Base* p = new Derived(1);
0064   v1.push_back(p);
0065   v2.push_back(p);
0066 }
0067   */
0068   // void guy_on_stack()
0069   // {
0070   //   edm::OwnVector<Base> v;
0071   //   Derived d(10);
0072   //   v.push_back(&d);
0073   // }
0074 
0075   void copy_good_vec() {
0076     // v1 is perfectly fine...
0077     edm::OwnVector<Base> v1;
0078     Base* p = new Derived(100);
0079     v1.push_back(p);
0080     //v1.push_back(new Derived(100));
0081 
0082     // But what if we copy him?
0083     edm::OwnVector<Base> v2(v1);
0084   }
0085 
0086   void assign_to_other() {
0087     edm::OwnVector<Base> v1;
0088     Base* p = new Derived(100);
0089     v1.push_back(p);
0090 
0091     edm::OwnVector<Base> v2;
0092     v2 = v1;
0093   }
0094 
0095   void do_assign(edm::OwnVector<Base>& iLHS, edm::OwnVector<Base>& iRHS) { iLHS = iRHS; }
0096 
0097   void assign_to_self() {
0098     // Self-assignment happens, often by accident...
0099     edm::OwnVector<Base> v1;
0100     v1.push_back(new Derived(100));
0101     auto& v2 = v1;
0102     do_assign(v1, v2);
0103   }
0104 
0105   void pop_one() {
0106     edm::OwnVector<Base> v1;
0107     v1.push_back(new Derived(100));
0108     v1.pop_back();
0109   }
0110 
0111   void back_with_null_pointer() {
0112     edm::OwnVector<Base> v;
0113     Base* p = 0;
0114     v.push_back(p);
0115     try {
0116       v.back();
0117       assert("Failed to throw a required exception in OwnVector_t" == 0);
0118     } catch (edm::Exception& x) {
0119       // this is expected.
0120     } catch (...) {
0121       throw;
0122     }
0123   }
0124 
0125   void take_an_rvalue() {
0126     edm::OwnVector<Base> v;
0127     v.push_back(new Derived(101));
0128     Derived d(102);
0129     v.push_back(d.clone());
0130   }
0131 
0132   void take_an_lvalue() {
0133     edm::OwnVector<Base> v1;
0134     Base* p = new Derived(100);
0135     v1.push_back(p);
0136 
0137     assert(p == nullptr);
0138   }
0139 
0140   void take_an_auto_ptr() {
0141     edm::OwnVector<Base> v1;
0142     std::unique_ptr<Base> p = std::make_unique<Derived>(100);
0143     v1.push_back(std::move(p));
0144     assert(p.get() == nullptr);
0145   }
0146 
0147   void set_at_index() {
0148     edm::OwnVector<Base> v1;
0149     Base* p = new Derived(100);
0150     Base* backup = p;
0151     v1.push_back(p);
0152     assert(p == nullptr);
0153     assert(&v1[0] == backup);
0154     Base* p2 = new Derived(101);
0155     Base* backup2 = p2;
0156     assert(backup2 != backup);
0157     v1.set(0, p2);
0158     assert(p2 == nullptr);
0159     assert(&v1[0] == backup2);
0160   }
0161 
0162   void insert_with_iter() {
0163     edm::OwnVector<Base> v1;
0164     Base *p[3], *backup[3];
0165     for (int i = 0; i < 3; ++i) {
0166       backup[i] = p[i] = new Derived(100 + i);
0167     }
0168     v1.push_back(p[0]);
0169     v1.push_back(p[2]);
0170     v1.insert(v1.begin() + 1, p[1]);
0171     assert(p[0] == nullptr);
0172     assert(p[1] == nullptr);
0173     assert(p[2] == nullptr);
0174     assert(&v1[0] == backup[0]);
0175     assert(&v1[1] == backup[1]);
0176     assert(&v1[2] == backup[2]);
0177   }
0178 
0179 }  // namespace
0180 
0181 int main() {
0182   edm::OwnVector<Base> vec;
0183   vec.push_back(new Derived(100));
0184   edm::OwnVector<Base>* p = new edm::OwnVector<Base>;
0185   p->push_back(new Derived(2));
0186   delete p;
0187   //   same_guy_twice();
0188   //   two_different_owners();
0189   //   guy_on_stack();
0190   copy_good_vec();
0191   assign_to_other();
0192   assign_to_self();
0193   pop_one();
0194   back_with_null_pointer();
0195 
0196   take_an_rvalue();
0197   take_an_lvalue();
0198   take_an_auto_ptr();
0199 
0200   set_at_index();
0201   insert_with_iter();
0202 }