File indexing completed on 2024-08-24 09:50:39
0001
0002
0003
0004
0005
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
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 }
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
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
0231
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
0241
0242
0243
0244
0245
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
0257 CPPUNIT_ASSERT(!(dummyPtr1 == dummyPtrNewPID));
0258 CPPUNIT_ASSERT(dummyPtr1 != dummyPtrNewPID);
0259
0260
0261
0262
0263 }
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289
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 }
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 }