Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 12:53:07

0001 /*
0002  *  reftobaseprod_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/RefToBaseProd.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 testRefToBaseProd : public CppUnit::TestFixture {
0029   CPPUNIT_TEST_SUITE(testRefToBaseProd);
0030 
0031   CPPUNIT_TEST(constructTest);
0032   CPPUNIT_TEST(getTest);
0033 
0034   CPPUNIT_TEST_SUITE_END();
0035 
0036 public:
0037   void setUp() {}
0038   void tearDown() {}
0039 
0040   void constructTest();
0041   void comparisonTest();
0042   void getTest();
0043 };
0044 
0045 ///registration of the test so that the runner can find it
0046 CPPUNIT_TEST_SUITE_REGISTRATION(testRefToBaseProd);
0047 
0048 namespace {
0049   struct Dummy {
0050     Dummy() {}
0051     virtual ~Dummy() {}
0052     bool operator==(Dummy const& iRHS) const { return this == &iRHS; }
0053     bool operator<(Dummy const& iRHS) const { return this->address() < iRHS.address(); }
0054     void const* address() const { return this; }
0055   };
0056 
0057   typedef std::vector<Dummy> DummyCollection;
0058 
0059   typedef std::set<Dummy> DummySet;
0060   typedef std::list<Dummy> DummyList;
0061   typedef std::deque<Dummy> DummyDeque;
0062 
0063   struct Dummy2 : public Dummy {
0064     Dummy2() {}
0065     virtual ~Dummy2() {}
0066   };
0067 
0068   typedef std::vector<Dummy2> DummyCollection2;
0069 
0070   template <typename T, typename C>
0071   void compareTo(const RefToBaseProd<T>& iProd, C const& iContainer) {
0072     unsigned int index = 0;
0073     for (auto const& item : iContainer) {
0074       CPPUNIT_ASSERT(&((*iProd.get())[index++]) == &item);
0075     }
0076     index = 0;
0077     for (auto const& item : iContainer) {
0078       CPPUNIT_ASSERT(&((*iProd)[index++]) == &item);
0079     }
0080     index = 0;
0081     for (auto const& item : iContainer) {
0082       CPPUNIT_ASSERT(&((*(iProd.operator->()))[index++]) == &item);
0083     }
0084     index = 0;
0085     for (auto const& item : iContainer) {
0086       CPPUNIT_ASSERT(&(iProd->at(index++)) == &item);
0087     }
0088   }
0089 }  // namespace
0090 
0091 void testRefToBaseProd::constructTest() {
0092   RefToBaseProd<Dummy> nulled;
0093   CPPUNIT_ASSERT(!nulled);
0094   CPPUNIT_ASSERT(nulled.isNull());
0095   CPPUNIT_ASSERT(!nulled.isNonnull());
0096 
0097   RefToBaseProd<Dummy> nulledP;
0098   CPPUNIT_ASSERT(!nulledP);
0099   CPPUNIT_ASSERT(nulledP.isNull());
0100   CPPUNIT_ASSERT(!nulledP.isNonnull());
0101 
0102   ProductID const pid(1, 1);
0103 
0104   {
0105     Dummy const dummy;
0106     DummyCollection dummyContainer;
0107     dummyContainer.push_back(dummy);
0108     dummyContainer.push_back(dummy);
0109     dummyContainer.push_back(dummy);
0110     OrphanHandle<DummyCollection> handle(&dummyContainer, pid);
0111     RefToBaseProd<Dummy> dummyPtr(handle);
0112 
0113     CPPUNIT_ASSERT(dummyPtr.id() == pid);
0114     compareTo(dummyPtr, dummyContainer);
0115   }
0116 
0117   {
0118     Dummy const dummy;
0119     DummySet dummyContainer;
0120     dummyContainer.insert(dummy);
0121     dummyContainer.insert(dummy);
0122     dummyContainer.insert(dummy);
0123     OrphanHandle<DummySet> handle(&dummyContainer, pid);
0124     RefToBaseProd<Dummy> dummyPtr(handle);
0125 
0126     CPPUNIT_ASSERT(dummyPtr.id() == pid);
0127     compareTo(dummyPtr, dummyContainer);
0128   }
0129 
0130   {
0131     Dummy const dummy;
0132     DummyList dummyContainer;
0133     dummyContainer.push_back(dummy);
0134     dummyContainer.push_back(dummy);
0135     dummyContainer.push_back(dummy);
0136     OrphanHandle<DummyList> handle(&dummyContainer, pid);
0137     RefToBaseProd<Dummy> dummyPtr(handle);
0138 
0139     CPPUNIT_ASSERT(dummyPtr.id() == pid);
0140     compareTo(dummyPtr, dummyContainer);
0141   }
0142 
0143   {
0144     Dummy const dummy;
0145     DummyDeque dummyContainer;
0146     dummyContainer.push_back(dummy);
0147     dummyContainer.push_back(dummy);
0148     dummyContainer.push_back(dummy);
0149     OrphanHandle<DummyDeque> handle(&dummyContainer, pid);
0150     RefToBaseProd<Dummy> dummyPtr(handle);
0151 
0152     CPPUNIT_ASSERT(dummyPtr.id() == pid);
0153     compareTo(dummyPtr, dummyContainer);
0154   }
0155 
0156   {
0157     Dummy2 const dummy;
0158     DummyCollection2 dummyContainer;
0159     dummyContainer.push_back(dummy);
0160     dummyContainer.push_back(dummy);
0161     dummyContainer.push_back(dummy);
0162     OrphanHandle<DummyCollection2> handle(&dummyContainer, pid);
0163     RefToBaseProd<Dummy> dummyPtr(handle);
0164     RefToBaseProd<Dummy> dummyPtr2(dummyPtr);
0165 
0166     CPPUNIT_ASSERT(dummyPtr.id() == pid);
0167     compareTo(dummyPtr, dummyContainer);
0168 
0169     CPPUNIT_ASSERT(dummyPtr2.id() == pid);
0170     compareTo(dummyPtr2, dummyContainer);
0171   }
0172 }
0173 
0174 namespace {
0175   struct TestGetter : public edm::EDProductGetter {
0176     WrapperBase const* hold_;
0177     WrapperBase const* getIt(ProductID const&) const override { return hold_; }
0178     std::optional<std::tuple<edm::WrapperBase const*, unsigned int>> getThinnedProduct(ProductID const&,
0179                                                                                        unsigned int) const override {
0180       return std::nullopt;
0181     }
0182 
0183     void getThinnedProducts(ProductID const& pid,
0184                             std::vector<WrapperBase const*>& wrappers,
0185                             std::vector<unsigned int>& keys) const override {}
0186 
0187     edm::OptionalThinnedKey getThinnedKeyFrom(ProductID const&, unsigned int, ProductID const&) const override {
0188       return std::monostate{};
0189     }
0190 
0191     unsigned int transitionIndex_() const override { return 0U; }
0192 
0193     TestGetter() : hold_() {}
0194   };
0195 }  // namespace
0196 
0197 void testRefToBaseProd::getTest() {
0198   {
0199     typedef std::vector<IntValue> IntCollection;
0200     auto ptr = std::make_unique<IntCollection>();
0201 
0202     ptr->push_back(0);
0203     ptr->push_back(1);
0204 
0205     edm::Wrapper<IntCollection> wrapper(std::move(ptr));
0206     TestGetter tester;
0207     tester.hold_ = &wrapper;
0208 
0209     ProductID const pid(1, 1);
0210 
0211     IntCollection const* wptr = dynamic_cast<IntCollection const*>(wrapper.product());
0212 
0213     OrphanHandle<IntCollection> handle(wptr, pid);
0214 
0215     //NOTE: ROOT will touch the private variables directly and since the RefToBaseProd
0216     // has no constructor which takes RefCore, I have to play this dirty trick
0217     assert(sizeof(edm::RefCore) == sizeof(edm::RefToBaseProd<IntValue>));
0218 
0219     RefCore core(pid, nullptr, &tester, false);
0220     RefToBaseProd<IntValue>& prod = reinterpret_cast<RefToBaseProd<IntValue>&>(core);
0221 
0222     //previously making a copy before reading back would cause seg fault
0223     RefToBaseProd<IntValue> prodCopy(prod);
0224 
0225     CPPUNIT_ASSERT(!prod.hasCache());
0226 
0227     CPPUNIT_ASSERT(0 != prod.get());
0228     CPPUNIT_ASSERT(prod.hasCache());
0229     compareTo(prod, *wptr);
0230 
0231     CPPUNIT_ASSERT(!prodCopy.hasCache());
0232 
0233     CPPUNIT_ASSERT(0 != prodCopy.get());
0234     CPPUNIT_ASSERT(prodCopy.hasCache());
0235     compareTo(prodCopy, *wptr);
0236   }
0237   {
0238     typedef std::vector<IntValue2> SDCollection;
0239     auto ptr = std::make_unique<SDCollection>();
0240 
0241     ptr->push_back(IntValue2(0));
0242     ptr->back().value_ = 0;
0243     ptr->push_back(IntValue2(1));
0244     ptr->back().value_ = 1;
0245 
0246     edm::Wrapper<SDCollection> wrapper(std::move(ptr));
0247     TestGetter tester;
0248     tester.hold_ = &wrapper;
0249 
0250     ProductID const pid(1, 1);
0251 
0252     SDCollection const* wptr = dynamic_cast<SDCollection const*>(wrapper.product());
0253 
0254     OrphanHandle<SDCollection> handle(wptr, pid);
0255 
0256     //NOTE: ROOT will touch the private variables directly and since the RefToBaseProd
0257     // has no constructor which takes RefCore, I have to play this dirty trick
0258     assert(sizeof(edm::RefCore) == sizeof(edm::RefToBaseProd<IntValue>));
0259 
0260     RefCore core(pid, nullptr, &tester, false);
0261     RefToBaseProd<IntValue>& prod = reinterpret_cast<RefToBaseProd<IntValue>&>(core);
0262 
0263     CPPUNIT_ASSERT(!prod.hasCache());
0264 
0265     CPPUNIT_ASSERT(0 != prod.get());
0266     CPPUNIT_ASSERT(prod.hasCache());
0267     compareTo(prod, *wptr);
0268   }
0269 
0270   {
0271     TestGetter tester;
0272     tester.hold_ = nullptr;
0273     ProductID const pid(1, 1);
0274 
0275     //NOTE: ROOT will touch the private variables directly and since the RefToBaseProd
0276     // has no constructor which takes RefCore, I have to play this dirty trick
0277     assert(sizeof(edm::RefCore) == sizeof(edm::RefToBaseProd<IntValue>));
0278 
0279     RefCore core(pid, nullptr, &tester, false);
0280     RefToBaseProd<IntValue>& prod = reinterpret_cast<RefToBaseProd<IntValue>&>(core);
0281 
0282     CPPUNIT_ASSERT_THROW((*prod), cms::Exception);
0283     CPPUNIT_ASSERT_THROW((prod.operator->()), cms::Exception);
0284   }
0285 }