Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 /*
0002  *  ref_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 "DataFormats/Common/interface/EDProductGetter.h"
0012 #include "DataFormats/Common/interface/OrphanHandle.h"
0013 
0014 #include "DataFormats/Common/interface/Ref.h"
0015 #include "DataFormats/Common/interface/RefProd.h"
0016 #include "DataFormats/Common/interface/RefToBaseProd.h"
0017 #include <iostream>
0018 using namespace edm;
0019 
0020 class testRef : public CppUnit::TestFixture {
0021   CPPUNIT_TEST_SUITE(testRef);
0022 
0023   CPPUNIT_TEST(constructTest);
0024   CPPUNIT_TEST(comparisonTest);
0025   CPPUNIT_TEST(getTest);
0026 
0027   CPPUNIT_TEST_SUITE_END();
0028 
0029 public:
0030   void setUp() {}
0031   void tearDown() {}
0032 
0033   void constructTest();
0034   void comparisonTest();
0035   void getTest();
0036 };
0037 
0038 ///registration of the test so that the runner can find it
0039 CPPUNIT_TEST_SUITE_REGISTRATION(testRef);
0040 
0041 namespace {
0042   struct Dummy {
0043     Dummy() {}
0044     ~Dummy() {}
0045     bool operator==(Dummy const& iRHS) const { return this == &iRHS; }
0046     void const* address() const { return this; }
0047   };
0048 
0049   typedef std::vector<Dummy> DummyCollection;
0050 }  // namespace
0051 
0052 void testRef::constructTest() {
0053   Ref<DummyCollection> nulled;
0054   CPPUNIT_ASSERT(!nulled);
0055   CPPUNIT_ASSERT(nulled.isNull());
0056   CPPUNIT_ASSERT(!nulled.isNonnull());
0057 
0058   Ref<DummyCollection> nulledP;
0059   CPPUNIT_ASSERT(!nulledP);
0060   CPPUNIT_ASSERT(nulledP.isNull());
0061   CPPUNIT_ASSERT(!nulledP.isNonnull());
0062 
0063   ProductID const pid(1, 1);
0064 
0065   unsigned int const key = 2;
0066   Dummy const dummy;
0067   DummyCollection dummyCollection;
0068   dummyCollection.push_back(dummy);
0069   dummyCollection.push_back(dummy);
0070   dummyCollection.push_back(dummy);
0071   OrphanHandle<DummyCollection> handle(&dummyCollection, pid);
0072   Ref<DummyCollection> dummyRef(handle, key);
0073   RefProd<DummyCollection> dummyRefProd(handle);
0074 
0075   CPPUNIT_ASSERT(dummyRef.id() == pid);
0076   CPPUNIT_ASSERT(dummyRefProd.id() == pid);
0077   CPPUNIT_ASSERT(dummyRef.key() == key);
0078   CPPUNIT_ASSERT(&(*dummyRef) == &dummyCollection[key]);
0079   CPPUNIT_ASSERT((dummyRef.operator->()) == &dummyCollection[key]);
0080   CPPUNIT_ASSERT(dummyRef->address() == dummyCollection[key].address());
0081   CPPUNIT_ASSERT(&(*dummyRefProd) == &dummyCollection);
0082   CPPUNIT_ASSERT((dummyRefProd.operator->()) == &dummyCollection);
0083 
0084   Ref<DummyCollection> testRef1(pid, &dummyCollection[key], key, nullptr);
0085   CPPUNIT_ASSERT(testRef1.get() == &dummyCollection[key] && testRef1.key() == key && testRef1.isTransient() == false &&
0086                  testRef1.id() == pid);
0087 
0088   Ref<DummyCollection> testRef2(pid, &dummyCollection[key], key);
0089   CPPUNIT_ASSERT(testRef2.get() == &dummyCollection[key] && testRef2.key() == key && testRef2.isTransient() == false &&
0090                  testRef2.id() == pid);
0091 
0092   Ref<DummyCollection> testRef3(pid, &dummyCollection[key], key, false);
0093   CPPUNIT_ASSERT(testRef3.get() == &dummyCollection[key] && testRef3.key() == key && testRef3.isTransient() == false &&
0094                  testRef3.id() == pid);
0095 
0096   Ref<DummyCollection> testRef4(pid, &dummyCollection[key], key, true);
0097   CPPUNIT_ASSERT(testRef4.get() == &dummyCollection[key] && testRef4.key() == key && testRef4.isTransient() == true &&
0098                  testRef4.id() == pid);
0099 
0100   Ref<DummyCollection> testRef5(&dummyCollection, key);
0101   CPPUNIT_ASSERT(testRef5.get() == &dummyCollection[key] && testRef5.key() == key && testRef5.isTransient() == true &&
0102                  testRef5.id() == edm::ProductID());
0103 }
0104 
0105 void testRef::comparisonTest() {
0106   {
0107     ProductID const pid(1, 1);
0108 
0109     unsigned int const key = 2;
0110     Dummy const dummy;
0111     DummyCollection dummyCollection;
0112     dummyCollection.push_back(dummy);
0113     OrphanHandle<DummyCollection> handle(&dummyCollection, pid);
0114     OrphanHandle<DummyCollection> handle2(&dummyCollection, pid);
0115     Ref<DummyCollection> dummyRef1(handle, key);
0116     Ref<DummyCollection> dummyRef2(handle2, key);
0117     RefProd<DummyCollection> dummyRefProd1(handle);
0118     RefProd<DummyCollection> dummyRefProd2(handle2);
0119 
0120     CPPUNIT_ASSERT(dummyRef1 == dummyRef2);
0121     CPPUNIT_ASSERT(!(dummyRef1 != dummyRef2));
0122     CPPUNIT_ASSERT(!(dummyRef1 < dummyRef2));
0123     CPPUNIT_ASSERT(!(dummyRef2 < dummyRef1));
0124     CPPUNIT_ASSERT(!(dummyRef1 < dummyRef1));
0125     CPPUNIT_ASSERT(!(dummyRef2 < dummyRef2));
0126 
0127     CPPUNIT_ASSERT(dummyRefProd1 == dummyRefProd2);
0128     CPPUNIT_ASSERT(!(dummyRefProd1 != dummyRefProd2));
0129     CPPUNIT_ASSERT(!(dummyRefProd1 < dummyRefProd2));
0130     CPPUNIT_ASSERT(!(dummyRefProd2 < dummyRefProd1));
0131     CPPUNIT_ASSERT(!(dummyRefProd1 < dummyRefProd1));
0132     CPPUNIT_ASSERT(!(dummyRefProd2 < dummyRefProd2));
0133 
0134     Ref<DummyCollection> dummyRefNewKey(handle, key + 1);
0135     CPPUNIT_ASSERT(!(dummyRef1 == dummyRefNewKey));
0136     CPPUNIT_ASSERT(dummyRef1 != dummyRefNewKey);
0137     CPPUNIT_ASSERT(dummyRef1 < dummyRefNewKey);
0138     CPPUNIT_ASSERT(!(dummyRefNewKey < dummyRef1));
0139 
0140     ProductID const pidOther(1, 4);
0141     OrphanHandle<DummyCollection> handleNewPID(&dummyCollection, pidOther);
0142     Ref<DummyCollection> dummyRefNewPID(handleNewPID, key);
0143     RefProd<DummyCollection> dummyRefProdNewPID(handleNewPID);
0144     CPPUNIT_ASSERT(!(dummyRef1 == dummyRefNewPID));
0145     CPPUNIT_ASSERT(dummyRef1 != dummyRefNewPID);
0146     CPPUNIT_ASSERT(!(dummyRefProd1 == dummyRefProdNewPID));
0147     CPPUNIT_ASSERT(dummyRefProd1 != dummyRefProdNewPID);
0148     CPPUNIT_ASSERT(dummyRefProd1 < dummyRefProdNewPID);
0149     CPPUNIT_ASSERT(!(dummyRefProdNewPID < dummyRefProd1));
0150   }
0151   {
0152     typedef std::map<int, double> DummyCollection2;
0153     ProductID const pid2(1, 2);
0154     DummyCollection2 dummyCollection2;
0155     dummyCollection2.insert(std::make_pair(1, 1.0));
0156     dummyCollection2.insert(std::make_pair(2, 2.0));
0157     OrphanHandle<DummyCollection2> handle2(&dummyCollection2, pid2);
0158     Ref<DummyCollection2> dummyRef21(handle2, 1);
0159     Ref<DummyCollection2> dummyRef22(handle2, 2);
0160     CPPUNIT_ASSERT(dummyRef21 != dummyRef22);
0161     CPPUNIT_ASSERT(dummyRef21 < dummyRef22);
0162     CPPUNIT_ASSERT(!(dummyRef22 < dummyRef21));
0163 
0164     typedef std::map<int, double, std::greater<int>> DummyCollection3;
0165     ProductID const pid3(1, 3);
0166     DummyCollection3 dummyCollection3;
0167     dummyCollection3.insert(std::make_pair(1, 1.0));
0168     dummyCollection3.insert(std::make_pair(2, 2.0));
0169     OrphanHandle<DummyCollection3> handle3(&dummyCollection3, pid3);
0170     Ref<DummyCollection3> dummyRef31(handle3, 1);
0171     Ref<DummyCollection3> dummyRef32(handle3, 2);
0172     CPPUNIT_ASSERT(dummyRef31 != dummyRef32);
0173     CPPUNIT_ASSERT(!(dummyRef31 < dummyRef32));
0174     CPPUNIT_ASSERT(dummyRef32 < dummyRef31);
0175   }
0176 }
0177 
0178 namespace {
0179   struct TestGetter : public edm::EDProductGetter {
0180     WrapperBase const* hold_;
0181     WrapperBase const* getIt(ProductID const&) const override { return hold_; }
0182 
0183     std::optional<std::tuple<edm::WrapperBase const*, unsigned int>> getThinnedProduct(ProductID const&,
0184                                                                                        unsigned int) const override {
0185       return std::nullopt;
0186     }
0187 
0188     void getThinnedProducts(ProductID const& pid,
0189                             std::vector<WrapperBase const*>& wrappers,
0190                             std::vector<unsigned int>& keys) const override {}
0191 
0192     edm::OptionalThinnedKey getThinnedKeyFrom(ProductID const&, unsigned int, ProductID const&) const override {
0193       return std::monostate{};
0194     }
0195 
0196     unsigned int transitionIndex_() const override { return 0U; }
0197     TestGetter() : hold_(nullptr) {}
0198   };
0199 
0200   struct IntValue {
0201     int value_;
0202     IntValue(int iValue) : value_(iValue) {}
0203   };
0204 }  // namespace
0205 
0206 void testRef::getTest() {
0207   typedef std::vector<IntValue> IntCollection;
0208   auto ptr = std::make_unique<IntCollection>();
0209 
0210   ptr->push_back(0);
0211   ptr->push_back(1);
0212 
0213   edm::Wrapper<IntCollection> wrapper(std::move(ptr));
0214   TestGetter tester;
0215   tester.hold_ = &wrapper;
0216 
0217   ProductID const pid(1, 1);
0218 
0219   IntCollection const* wptr = reinterpret_cast<IntCollection const*>(wrapper.product());
0220 
0221   OrphanHandle<IntCollection> handle(wptr, pid);
0222 
0223   Ref<IntCollection> ref0(pid, 0, &tester);
0224   CPPUNIT_ASSERT(!ref0.hasProductCache());
0225 
0226   Ref<IntCollection> ref1(pid, 1, &tester);
0227 
0228   CPPUNIT_ASSERT(0 == ref0->value_);
0229   CPPUNIT_ASSERT(ref0.hasProductCache());
0230   CPPUNIT_ASSERT(1 == ref1->value_);
0231   CPPUNIT_ASSERT(1 == (*ref1).value_);
0232 
0233   Ref<IntCollection> ref0FromHandle(handle, 0);
0234   CPPUNIT_ASSERT(0 == ref0FromHandle->value_);
0235   Ref<IntCollection> ref1FromHandle(handle, 1);
0236   CPPUNIT_ASSERT(1 == ref1FromHandle->value_);
0237 
0238   RefProd<IntCollection> refProd0(handle);
0239   refProd0.refCore().setProductGetter(&tester);
0240   //refProd0.refCore().setProductPtr(0);
0241 
0242   RefProd<IntCollection> refProd2(pid, &tester);
0243 
0244   CPPUNIT_ASSERT(0 == (*refProd0)[0].value_);
0245   CPPUNIT_ASSERT(1 == (*refProd0)[1].value_);
0246   CPPUNIT_ASSERT(1 == (*refProd2)[1].value_);
0247 
0248   //std::cerr << ">>> RefToBaseProd from RefProd" << std::endl;
0249   RefToBaseProd<IntValue> refToBaseProd0(refProd0);
0250   //std::cerr << ">>> RefToBaseProd from Handle" << std::endl;
0251   RefToBaseProd<IntValue> refToBaseProd2(handle);
0252   //std::cerr << ">>> checking View from RefToBaseProd" << std::endl;
0253   const View<IntValue>& vw = *refToBaseProd0;
0254   //std::cerr << ">>> checking View not empty" << std::endl;
0255   CPPUNIT_ASSERT(!vw.empty());
0256   //std::cerr << ">>> checking View size" << std::endl;
0257   CPPUNIT_ASSERT(vw.size() == 2);
0258   //std::cerr << ">>> checking View element #0" << std::endl;
0259   CPPUNIT_ASSERT(vw[0].value_ == ref0->value_);
0260   //std::cerr << ">>> checking View element #1" << std::endl;
0261   CPPUNIT_ASSERT(vw[1].value_ == ref1->value_);
0262   //std::cerr << ">>> RefToBaseProd from View" << std::endl;
0263 }