Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-08-24 09:50:39

0001 /*
0002  *  ptr_t.cppunit.cc
0003  *  CMSSW
0004  *
0005  *  Created by Chris Jones on 02/11/05.
0006  *
0007  */
0008 
0009 #include "cppunit/extensions/HelperMacros.h"
0010 #include <vector>
0011 #include <set>
0012 #include <list>
0013 #include <deque>
0014 #include "DataFormats/Common/interface/Ptr.h"
0015 
0016 #include "DataFormats/Common/interface/EDProductGetter.h"
0017 #include "DataFormats/Common/interface/OrphanHandle.h"
0018 #include "DataFormats/Common/interface/Wrapper.h"
0019 
0020 #include <iostream>
0021 
0022 #include "DataFormats/Common/interface/IntValues.h"
0023 #include <typeinfo>
0024 
0025 using namespace edm;
0026 using namespace test_with_dictionaries;
0027 
0028 class testPtr : public CppUnit::TestFixture {
0029   CPPUNIT_TEST_SUITE(testPtr);
0030 
0031   CPPUNIT_TEST(constructTest);
0032   CPPUNIT_TEST(comparisonTest);
0033   CPPUNIT_TEST(getTest);
0034 
0035   CPPUNIT_TEST_SUITE_END();
0036 
0037 public:
0038   void setUp() {}
0039   void tearDown() {}
0040 
0041   void constructTest();
0042   void comparisonTest();
0043   void getTest();
0044 };
0045 
0046 ///registration of the test so that the runner can find it
0047 CPPUNIT_TEST_SUITE_REGISTRATION(testPtr);
0048 
0049 namespace {
0050   struct Dummy {
0051     Dummy() {}
0052     virtual ~Dummy() {}
0053     bool operator==(Dummy const& iRHS) const { return this == &iRHS; }
0054     bool operator<(Dummy const& iRHS) const { return this->address() < iRHS.address(); }
0055     void const* address() const { return this; }
0056   };
0057 
0058   typedef std::vector<Dummy> DummyCollection;
0059 
0060   typedef std::set<Dummy> DummySet;
0061   typedef std::list<Dummy> DummyList;
0062   typedef std::deque<Dummy> DummyDeque;
0063 
0064   struct Dummy2 : public Dummy {
0065     Dummy2() {}
0066     virtual ~Dummy2() {}
0067   };
0068 
0069   typedef std::vector<Dummy2> DummyCollection2;
0070 }  // namespace
0071 
0072 void testPtr::constructTest() {
0073   Ptr<Dummy> nulled;
0074   CPPUNIT_ASSERT(!nulled);
0075   CPPUNIT_ASSERT(nulled.isNull());
0076   CPPUNIT_ASSERT(!nulled.isNonnull());
0077   CPPUNIT_ASSERT(!nulled.isAvailable());
0078 
0079   ProductID const pid(1, 1);
0080 
0081   {
0082     unsigned int const key = 2;
0083     Dummy const dummy;
0084     DummyCollection dummyContainer;
0085     dummyContainer.push_back(dummy);
0086     dummyContainer.push_back(dummy);
0087     dummyContainer.push_back(dummy);
0088     OrphanHandle<DummyCollection> handle(&dummyContainer, pid);
0089     Ptr<Dummy> dummyPtr(handle, key);
0090 
0091     CPPUNIT_ASSERT(dummyPtr.isAvailable());
0092     CPPUNIT_ASSERT(dummyPtr.id() == pid);
0093     CPPUNIT_ASSERT(dummyPtr.key() == key);
0094     CPPUNIT_ASSERT(dummyPtr.get() == &dummyContainer[key]);
0095     CPPUNIT_ASSERT(&(*dummyPtr) == &dummyContainer[key]);
0096     CPPUNIT_ASSERT((dummyPtr.operator->()) == &dummyContainer[key]);
0097     CPPUNIT_ASSERT(dummyPtr->address() == dummyContainer[key].address());
0098 
0099     Ptr<Dummy> anotherPtr(dummyPtr.id(), dummyPtr.get(), dummyPtr.key(), dummyPtr.isTransient());
0100     CPPUNIT_ASSERT(dummyPtr.get() == anotherPtr.get() && dummyPtr.key() == anotherPtr.key() &&
0101                    dummyPtr.isTransient() == anotherPtr.isTransient() && dummyPtr.id() == anotherPtr.id());
0102 
0103     Ptr<Dummy> ptrTrans(&dummyContainer, key);
0104     Ptr<Dummy> ptrTrans2(&dummyContainer[key], key);
0105 
0106     CPPUNIT_ASSERT(ptrTrans.get() == &dummyContainer[key] && ptrTrans2.get() == &dummyContainer[key] &&
0107                    ptrTrans.id() == ProductID() && ptrTrans.id() == ptrTrans2.id() && ptrTrans.isTransient() &&
0108                    ptrTrans2.isTransient() && ptrTrans.key() == key && ptrTrans2.key() == key);
0109 
0110     Ptr<Dummy> ptrTrans3(nullptr, key);
0111     CPPUNIT_ASSERT(ptrTrans3.isNull());
0112   }
0113 
0114   {
0115     unsigned int const key = 2;
0116     Dummy const dummy;
0117     DummySet dummyContainer;
0118     dummyContainer.insert(dummy);
0119     dummyContainer.insert(dummy);
0120     dummyContainer.insert(dummy);
0121     OrphanHandle<DummySet> handle(&dummyContainer, pid);
0122     Ptr<Dummy> dummyPtr(handle, key);
0123 
0124     CPPUNIT_ASSERT(dummyPtr.isAvailable());
0125     CPPUNIT_ASSERT(dummyPtr.id() == pid);
0126     CPPUNIT_ASSERT(dummyPtr.key() == key);
0127     DummySet::const_iterator it = dummyContainer.begin();
0128     std::advance(it, key);
0129     CPPUNIT_ASSERT(dummyPtr.get() == it->address());
0130     CPPUNIT_ASSERT(&(*dummyPtr) == it->address());
0131     CPPUNIT_ASSERT((dummyPtr.operator->()) == it->address());
0132     CPPUNIT_ASSERT(dummyPtr->address() == it->address());
0133   }
0134 
0135   {
0136     unsigned int const key = 2;
0137     Dummy const dummy;
0138     DummyList dummyContainer;
0139     dummyContainer.push_back(dummy);
0140     dummyContainer.push_back(dummy);
0141     dummyContainer.push_back(dummy);
0142     OrphanHandle<DummyList> handle(&dummyContainer, pid);
0143     Ptr<Dummy> dummyPtr(handle, key);
0144 
0145     CPPUNIT_ASSERT(dummyPtr.isAvailable());
0146     CPPUNIT_ASSERT(dummyPtr.id() == pid);
0147     CPPUNIT_ASSERT(dummyPtr.key() == key);
0148     DummyList::const_iterator it = dummyContainer.begin();
0149     std::advance(it, key);
0150     CPPUNIT_ASSERT(dummyPtr.get() == it->address());
0151     CPPUNIT_ASSERT(&(*dummyPtr) == it->address());
0152     CPPUNIT_ASSERT((dummyPtr.operator->()) == it->address());
0153     CPPUNIT_ASSERT(dummyPtr->address() == it->address());
0154   }
0155 
0156   {
0157     unsigned int const key = 2;
0158     Dummy const dummy;
0159     DummyDeque dummyContainer;
0160     dummyContainer.push_back(dummy);
0161     dummyContainer.push_back(dummy);
0162     dummyContainer.push_back(dummy);
0163     OrphanHandle<DummyDeque> handle(&dummyContainer, pid);
0164     Ptr<Dummy> dummyPtr(handle, key);
0165 
0166     CPPUNIT_ASSERT(dummyPtr.isAvailable());
0167     CPPUNIT_ASSERT(dummyPtr.id() == pid);
0168     //CPPUNIT_ASSERT(dummyPtrProd.id() == pid);
0169     CPPUNIT_ASSERT(dummyPtr.key() == key);
0170     DummyDeque::const_iterator it = dummyContainer.begin();
0171     std::advance(it, key);
0172     CPPUNIT_ASSERT(dummyPtr.get() == it->address());
0173     CPPUNIT_ASSERT(&(*dummyPtr) == it->address());
0174     CPPUNIT_ASSERT((dummyPtr.operator->()) == it->address());
0175     CPPUNIT_ASSERT(dummyPtr->address() == it->address());
0176   }
0177 
0178   {
0179     unsigned int const key = 2;
0180     Dummy2 const dummy;
0181     DummyCollection2 dummyContainer;
0182     dummyContainer.push_back(dummy);
0183     dummyContainer.push_back(dummy);
0184     dummyContainer.push_back(dummy);
0185     OrphanHandle<DummyCollection2> handle(&dummyContainer, pid);
0186     Ptr<Dummy> dummyPtr(handle, key);
0187     Ptr<Dummy2> dummyPtr2(dummyPtr);
0188 
0189     CPPUNIT_ASSERT(dummyPtr.isAvailable());
0190     CPPUNIT_ASSERT(dummyPtr.id() == pid);
0191     CPPUNIT_ASSERT(dummyPtr.key() == key);
0192     CPPUNIT_ASSERT(dummyPtr.get() == &dummyContainer[key]);
0193     CPPUNIT_ASSERT(&(*dummyPtr) == &dummyContainer[key]);
0194     CPPUNIT_ASSERT((dummyPtr.operator->()) == &dummyContainer[key]);
0195     CPPUNIT_ASSERT(dummyPtr->address() == dummyContainer[key].address());
0196 
0197     CPPUNIT_ASSERT(dummyPtr2.isAvailable());
0198     CPPUNIT_ASSERT(dummyPtr2.id() == pid);
0199     CPPUNIT_ASSERT(dummyPtr2.key() == key);
0200     CPPUNIT_ASSERT(dummyPtr2.get() == &dummyContainer[key]);
0201     CPPUNIT_ASSERT(&(*dummyPtr2) == &dummyContainer[key]);
0202     CPPUNIT_ASSERT((dummyPtr2.operator->()) == &dummyContainer[key]);
0203     CPPUNIT_ASSERT(dummyPtr2->address() == dummyContainer[key].address());
0204 
0205     Ptr<Dummy2> dummy2Ptr(handle, key);
0206     Ptr<Dummy> copyPtr(dummy2Ptr);
0207     CPPUNIT_ASSERT(dummy2Ptr.key() == copyPtr.key());
0208     CPPUNIT_ASSERT(dummy2Ptr.get() == static_cast<const Dummy*>(dummy2Ptr.get()));
0209 
0210     Ptr<Dummy> copyCtrPtr(copyPtr);
0211     CPPUNIT_ASSERT(copyPtr.key() == copyCtrPtr.key());
0212 
0213     Ptr<Dummy> movePtr(std::move(copyPtr));
0214     CPPUNIT_ASSERT(dummy2Ptr.key() == movePtr.key());
0215   }
0216 }
0217 
0218 void testPtr::comparisonTest() {
0219   {
0220     ProductID const pid(1, 1);
0221 
0222     unsigned int const key = 2;
0223     Dummy const dummy;
0224     DummyCollection dummyContainer;
0225     dummyContainer.push_back(dummy);
0226     OrphanHandle<DummyCollection> handle(&dummyContainer, pid);
0227     OrphanHandle<DummyCollection> handle2(&dummyContainer, pid);
0228     Ptr<Dummy> dummyPtr1(handle, key);
0229     Ptr<Dummy> dummyPtr2(handle2, key);
0230     //PtrProd<DummyCollection> dummyPtrProd1(handle);
0231     //PtrProd<DummyCollection> dummyPtrProd2(handle2);
0232 
0233     CPPUNIT_ASSERT(dummyPtr1 == dummyPtr2);
0234     CPPUNIT_ASSERT(!(dummyPtr1 != dummyPtr2));
0235     CPPUNIT_ASSERT(!(dummyPtr1 < dummyPtr2));
0236     CPPUNIT_ASSERT(!(dummyPtr2 < dummyPtr1));
0237     CPPUNIT_ASSERT(!(dummyPtr1 < dummyPtr1));
0238     CPPUNIT_ASSERT(!(dummyPtr2 < dummyPtr2));
0239 
0240     /*   CPPUNIT_ASSERT(dummyPtrProd1 == dummyPtrProd2);
0241    CPPUNIT_ASSERT(!(dummyPtrProd1 != dummyPtrProd2));
0242    CPPUNIT_ASSERT(!(dummyPtrProd1 < dummyPtrProd2));
0243    CPPUNIT_ASSERT(!(dummyPtrProd2 < dummyPtrProd1));
0244    CPPUNIT_ASSERT(!(dummyPtrProd1 < dummyPtrProd1));
0245    CPPUNIT_ASSERT(!(dummyPtrProd2 < dummyPtrProd2)); */
0246 
0247     Ptr<Dummy> dummyPtrNewKey(handle, key + 1);
0248     CPPUNIT_ASSERT(!(dummyPtr1 == dummyPtrNewKey));
0249     CPPUNIT_ASSERT(dummyPtr1 != dummyPtrNewKey);
0250     CPPUNIT_ASSERT(dummyPtr1 < dummyPtrNewKey);
0251     CPPUNIT_ASSERT(!(dummyPtrNewKey < dummyPtr1));
0252 
0253     ProductID const pidOther(1, 4);
0254     OrphanHandle<DummyCollection> handleNewPID(&dummyContainer, pidOther);
0255     Ptr<Dummy> dummyPtrNewPID(handleNewPID, key);
0256     //PtrProd<DummyCollection> dummyPtrProdNewPID(handleNewPID);
0257     CPPUNIT_ASSERT(!(dummyPtr1 == dummyPtrNewPID));
0258     CPPUNIT_ASSERT(dummyPtr1 != dummyPtrNewPID);
0259     /*CPPUNIT_ASSERT(!(dummyPtrProd1 == dummyPtrProdNewPID));
0260    CPPUNIT_ASSERT(dummyPtrProd1 != dummyPtrProdNewPID);
0261    CPPUNIT_ASSERT(dummyPtrProd1 < dummyPtrProdNewPID);
0262    CPPUNIT_ASSERT(!(dummyPtrProdNewPID < dummyPtrProd1)); */
0263   }
0264   /*
0265    
0266 {
0267    typedef std::map<int, double> DummyCollection2;
0268    ProductID const pid2(1, 2);
0269    DummyCollection2 dummyContainer2;
0270    dummyContainer2.insert(std::make_pair(1, 1.0));
0271    dummyContainer2.insert(std::make_pair(2, 2.0));
0272    OrphanHandle<DummyCollection2> handle2(&dummyContainer2, pid2);
0273    Ptr<DummyCollection2> dummyPtr21(handle2, 1);
0274    Ptr<DummyCollection2> dummyPtr22(handle2, 2);
0275    CPPUNIT_ASSERT(dummyPtr21 != dummyPtr22);
0276    CPPUNIT_ASSERT(dummyPtr21 < dummyPtr22);
0277    CPPUNIT_ASSERT(!(dummyPtr22 < dummyPtr21));
0278 
0279    typedef std::map<int, double, std::greater<int> > DummyCollection3;
0280    ProductID const pid3(1, 3);
0281    DummyCollection3 dummyContainer3;
0282    dummyContainer3.insert(std::make_pair(1, 1.0));
0283    dummyContainer3.insert(std::make_pair(2, 2.0));
0284    OrphanHandle<DummyCollection3> handle3(&dummyContainer3, pid3);
0285    Ptr<DummyCollection3> dummyPtr31(handle3, 1);
0286    Ptr<DummyCollection3> dummyPtr32(handle3, 2);
0287    CPPUNIT_ASSERT(dummyPtr31 != dummyPtr32);
0288    CPPUNIT_ASSERT(!(dummyPtr31 < dummyPtr32));
0289    CPPUNIT_ASSERT(dummyPtr32 < dummyPtr31);
0290  }
0291 */
0292 }
0293 
0294 namespace {
0295   struct TestGetter : public edm::EDProductGetter {
0296     WrapperBase const* hold_;
0297     WrapperBase const* getIt(ProductID const&) const override { return hold_; }
0298     std::optional<std::tuple<edm::WrapperBase const*, unsigned int>> getThinnedProduct(ProductID const&,
0299                                                                                        unsigned int) const override {
0300       return std::nullopt;
0301     }
0302 
0303     void getThinnedProducts(ProductID const& pid,
0304                             std::vector<WrapperBase const*>& wrappers,
0305                             std::vector<unsigned int>& keys) const override {}
0306 
0307     edm::OptionalThinnedKey getThinnedKeyFrom(ProductID const&, unsigned int, ProductID const&) const override {
0308       return std::monostate{};
0309     }
0310 
0311     unsigned int transitionIndex_() const override { return 0U; }
0312 
0313     TestGetter() : hold_() {}
0314   };
0315 }  // namespace
0316 
0317 void testPtr::getTest() {
0318   {
0319     typedef std::vector<IntValue> IntCollection;
0320     auto ptr = std::make_unique<IntCollection>();
0321 
0322     ptr->push_back(0);
0323     ptr->push_back(1);
0324 
0325     edm::Wrapper<IntCollection> wrapper(std::move(ptr));
0326     TestGetter tester;
0327     tester.hold_ = &wrapper;
0328 
0329     ProductID const pid(1, 1);
0330 
0331     IntCollection const* wptr = dynamic_cast<IntCollection const*>(wrapper.product());
0332 
0333     OrphanHandle<IntCollection> handle(wptr, pid);
0334 
0335     Ptr<IntValue> ref0(pid, 0, &tester);
0336     CPPUNIT_ASSERT(!ref0.hasProductCache());
0337 
0338     Ptr<IntValue> ref1(pid, 1, &tester);
0339 
0340     Ptr<IntValue> ref2(pid, 1, &tester);
0341 
0342     CPPUNIT_ASSERT(ref0.isAvailable());
0343     CPPUNIT_ASSERT(0 == ref0->value_);
0344     CPPUNIT_ASSERT(ref0.hasProductCache());
0345     CPPUNIT_ASSERT(1 == ref1->value_);
0346     CPPUNIT_ASSERT(1 == ref2->value_);
0347     CPPUNIT_ASSERT(1 == (*ref1).value_);
0348   }
0349   {
0350     typedef std::vector<IntValue2> SDCollection;
0351     auto ptr = std::make_unique<SDCollection>();
0352 
0353     ptr->push_back(IntValue2(0));
0354     ptr->back().value_ = 0;
0355     ptr->push_back(IntValue2(1));
0356     ptr->back().value_ = 1;
0357 
0358     edm::Wrapper<SDCollection> wrapper(std::move(ptr));
0359     TestGetter tester;
0360     tester.hold_ = &wrapper;
0361 
0362     ProductID const pid(1, 1);
0363 
0364     SDCollection const* wptr = dynamic_cast<SDCollection const*>(wrapper.product());
0365 
0366     OrphanHandle<SDCollection> handle(wptr, pid);
0367 
0368     Ptr<IntValue> ref0(pid, 0, &tester);
0369     CPPUNIT_ASSERT(!ref0.hasProductCache());
0370 
0371     Ptr<IntValue> ref1(pid, 1, &tester);
0372 
0373     Ptr<IntValue> ref2(pid, 1, &tester);
0374 
0375     CPPUNIT_ASSERT(0 == ref0->value_);
0376     CPPUNIT_ASSERT(ref0.hasProductCache());
0377     CPPUNIT_ASSERT(1 == ref1->value_);
0378     CPPUNIT_ASSERT(1 == ref2->value_);
0379     CPPUNIT_ASSERT(1 == (*ref1).value_);
0380   }
0381 
0382   {
0383     TestGetter tester;
0384     tester.hold_ = nullptr;
0385     ProductID const pid(1, 1);
0386 
0387     Ptr<IntValue> ref0(pid, 0, &tester);
0388     CPPUNIT_ASSERT_THROW((*ref0), cms::Exception);
0389     CPPUNIT_ASSERT_THROW((ref0.operator->()), cms::Exception);
0390   }
0391 }