Base

Inherit1

Inherit2

TestGetter

testPtrVector

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200

#include "DataFormats/Common/interface/PtrVector.h"
#include "DataFormats/Common/interface/TestHandle.h"
#include "DataFormats/Common/interface/Wrapper.h"
#include "DataFormats/Common/interface/IntValues.h"

#include "cppunit/extensions/HelperMacros.h"

#include <algorithm>
#include <iostream>
#include <vector>

class testPtrVector : public CppUnit::TestFixture {
  CPPUNIT_TEST_SUITE(testPtrVector);
  CPPUNIT_TEST(check);
  CPPUNIT_TEST(get);
  CPPUNIT_TEST_SUITE_END();

public:
  void setUp() {}
  void tearDown() {}
  void check();
  void get();
};

CPPUNIT_TEST_SUITE_REGISTRATION(testPtrVector);

namespace testPtr {
  struct Base {
    virtual ~Base() {}
    virtual int val() const = 0;
    bool operator==(Base const& other) const { return val() == other.val(); }
  };

  struct Inherit1 : public Base {
    virtual int val() const { return 1; }
  };
  struct Inherit2 : public Base {
    virtual int val() const { return 2; }
  };

  struct TestGetter : public edm::EDProductGetter {
    edm::WrapperBase const* hold_;
    edm::WrapperBase const* getIt(edm::ProductID const&) const override { return hold_; }
    std::optional<std::tuple<edm::WrapperBase const*, unsigned int>> getThinnedProduct(edm::ProductID const&,
                                                                                       unsigned int) const override {
      return std::nullopt;
    }

    void getThinnedProducts(edm::ProductID const& pid,
                            std::vector<edm::WrapperBase const*>& wrappers,
                            std::vector<unsigned int>& keys) const override {}

    edm::OptionalThinnedKey getThinnedKeyFrom(edm::ProductID const&,
                                              unsigned int,
                                              edm::ProductID const&) const override {
      return std::monostate{};
    }

    unsigned int transitionIndex_() const override { return 0U; }

    TestGetter() : hold_() {}
  };
}  // namespace testPtr

using namespace testPtr;

void do_some_tests(edm::PtrVector<Base> const& x) {
  edm::PtrVector<Base> copy(x);

  CPPUNIT_ASSERT(x.empty() == copy.empty());
  CPPUNIT_ASSERT(x.size() == copy.size());
  edm::PtrVector<Base>::const_iterator b = x.begin(), e = x.end(), cb = copy.begin(), ce = copy.end();
  CPPUNIT_ASSERT(e - b == ce - cb);
  CPPUNIT_ASSERT(std::distance(b, e) == std::distance(cb, ce));
}

void testPtrVector::check() {
  using namespace edm;

  std::vector<Inherit1> v1(2, Inherit1());
  std::vector<Inherit2> v2(2, Inherit2());

  TestHandle<std::vector<Inherit1>> h1(&v1, ProductID(1, 1));
  PtrVector<Inherit1> rv1;
  rv1.push_back(Ptr<Inherit1>(h1, 0));
  rv1.push_back(Ptr<Inherit1>(h1, 1));
  TestHandle<std::vector<Inherit2>> h2(&v2, ProductID(1, 2));
  PtrVector<Inherit2> rv2;
  rv2.push_back(Ptr<Inherit2>(h2, 0));
  rv2.push_back(Ptr<Inherit2>(h2, 1));

  PtrVector<Base> empty;
  PtrVector<Base> copy_of_empty(empty);

  CPPUNIT_ASSERT(empty == copy_of_empty);

  PtrVector<Base> bv1(rv1);
  Ptr<Base> r1_0 = bv1[0];
  Ptr<Base> r1_1 = bv1[1];
  PtrVector<Base> bv2(rv2);
  Ptr<Base> r2_0 = bv2[0];
  Ptr<Base> r2_1 = bv2[1];

  CPPUNIT_ASSERT(bv1.empty() == false);
  CPPUNIT_ASSERT(bv1.size() == 2);
  CPPUNIT_ASSERT(bv2.size() == 2);
  CPPUNIT_ASSERT(r1_0->val() == 1);
  CPPUNIT_ASSERT(r1_1->val() == 1);
  CPPUNIT_ASSERT(r2_0->val() == 2);
  CPPUNIT_ASSERT(r2_1->val() == 2);

  PtrVector<Base>::const_iterator b = bv1.begin(), e = bv1.end();
  PtrVector<Base>::const_iterator i = b;
  CPPUNIT_ASSERT((*i)->val() == 1);
  CPPUNIT_ASSERT(i != e);
  CPPUNIT_ASSERT(i - b == 0);
  ++i;
  CPPUNIT_ASSERT((*i)->val() == 1);
  CPPUNIT_ASSERT(i != e);
  CPPUNIT_ASSERT(i - b == 1);
  ++i;
  CPPUNIT_ASSERT(i == e);

  PtrVector<Base> assigned_from_bv1;
  do_some_tests(assigned_from_bv1);
  CPPUNIT_ASSERT(assigned_from_bv1.empty());
  assigned_from_bv1 = bv1;
  CPPUNIT_ASSERT(assigned_from_bv1.size() == bv1.size());
  CPPUNIT_ASSERT(std::equal(bv1.begin(), bv1.end(), assigned_from_bv1.begin()));
  CPPUNIT_ASSERT(assigned_from_bv1 == bv1);

  do_some_tests(assigned_from_bv1);

  /// creation of empty vector adding with push_back
  PtrVector<Base> bv3;
  bv3.push_back(r1_0);
  CPPUNIT_ASSERT(bv3.size() == 1);
  CPPUNIT_ASSERT(&(*r1_0) == &(*bv3[0]));
  bv3.push_back(r1_1);
  CPPUNIT_ASSERT(bv3.size() == 2);
  CPPUNIT_ASSERT(&(*r1_1) == &(*bv3[1]));

  /// clearing, then pushing in Ptr with other product ID
  bv3.clear();
  CPPUNIT_ASSERT(bv3.size() == 0);
  bv3.push_back(r2_0);
  CPPUNIT_ASSERT(bv3.size() == 1);
}

void testPtrVector::get() {
  using namespace test_with_dictionaries;
  typedef std::vector<IntValue> IntCollection;
  auto ptr = std::make_unique<IntCollection>();

  ptr->push_back(0);
  ptr->push_back(1);
  ptr->push_back(2);
  ptr->push_back(3);

  edm::Wrapper<IntCollection> wrapper(std::move(ptr));
  TestGetter tester;
  tester.hold_ = &wrapper;

  edm::ProductID const pid(1, 1);

  IntCollection const* wptr = dynamic_cast<IntCollection const*>(wrapper.product());

  edm::PtrVector<IntValue> iVec;
  std::cerr << "pre push_backs" << std::endl;
  iVec.push_back(edm::Ptr<IntValue>(pid, 0, &tester));
  iVec.push_back(edm::Ptr<IntValue>(pid, 2, &tester));
  std::cerr << "post push_backs" << std::endl;

  iVec.setProductGetter(&tester);

  std::cerr << "pre size" << std::endl;
  CPPUNIT_ASSERT(iVec.size() == 2);
  std::cerr << "pre iterator diff" << std::endl;
  CPPUNIT_ASSERT(static_cast<size_t>(iVec.end() - iVec.begin()) == iVec.size());
  std::cerr << "address compare" << std::endl;
  CPPUNIT_ASSERT(&(*(*(iVec.begin()))) == &(*(wptr->begin())));
  std::cerr << "pre value deref" << std::endl;
  CPPUNIT_ASSERT((*(*(iVec.begin()))).value_ == 0);
  std::cerr << "pre value ->" << std::endl;
  CPPUNIT_ASSERT((*(iVec.begin()))->value_ == 0);
  std::cerr << "post everything" << std::endl;

  /*
  typedef std::vector<Inherit1> I1Collection;
  auto ptr = std::make_unique<I1Collection>();

  ptr->push_back(0);
  ptr->push_back(1);

  edm::Wrapper<I1Collection> wrapper(ptr);
  TestGetter tester;
  tester.hold_ = &wrapper;
  */
}