File indexing completed on 2021-02-14 12:53:06
0001
0002
0003
0004
0005 #include "DataFormats/Common/interface/DetSetVector.h"
0006 #include "DataFormats/Common/interface/Ref.h"
0007 #include "DataFormats/Common/interface/TestHandle.h"
0008 #include "DataFormats/Provenance/interface/ProductID.h"
0009
0010 #include <algorithm>
0011 #include <cassert>
0012 #include <iterator>
0013 #include <ostream>
0014 #include <stdexcept>
0015 #include <vector>
0016
0017 using namespace edm;
0018
0019
0020
0021
0022 namespace {
0023 bool is_null(const void* iPtr) { return iPtr == nullptr; }
0024 }
0025
0026 struct Empty {};
0027
0028 template <typename BASE>
0029 class ValueT : public BASE {
0030 public:
0031
0032 ValueT() : d_(0.0) {}
0033
0034
0035
0036 explicit ValueT(double d) : d_(d) {}
0037
0038
0039
0040 double val() const { return d_; }
0041
0042
0043 ~ValueT() {}
0044
0045
0046 bool operator<(ValueT const& other) const { return d_ < other.d_; }
0047
0048
0049
0050 private:
0051 double d_;
0052 };
0053
0054 typedef edm::DoNotSortUponInsertion DNS;
0055
0056 template <>
0057 bool ValueT<DNS>::operator<(ValueT<DNS> const& ) const {
0058 throw std::logic_error("You can't sort me!");
0059 }
0060
0061 typedef ValueT<Empty> Value;
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075 template <typename BASE>
0076 std::ostream& operator<<(std::ostream& os, ValueT<BASE> const& v) {
0077 os << " val: " << v.val();
0078 return os;
0079 }
0080
0081 typedef edm::DetSetVector<Value> coll_type;
0082 typedef coll_type::detset detset;
0083
0084 void check_outer_collection_order(coll_type const& c) {
0085 if (c.size() < 2)
0086 return;
0087 coll_type::const_iterator i = c.begin();
0088 coll_type::const_iterator e = c.end();
0089
0090 coll_type::const_iterator prev(i);
0091 ++i;
0092 for (; i != e; ++i, ++prev) {
0093
0094
0095 assert(prev->id < i->id);
0096 }
0097 }
0098
0099 void check_inner_collection_order(detset const& d) {
0100 if (d.data.size() < 2)
0101 return;
0102 detset::const_iterator i = d.data.begin();
0103 detset::const_iterator e = d.data.end();
0104
0105 detset::const_iterator prev(i);
0106 ++i;
0107 for (; i != e; ++i, ++prev) {
0108
0109
0110
0111
0112
0113 assert(!(*i < *prev));
0114 }
0115 }
0116
0117 void printDetSet(detset const& ds, std::ostream& os) {
0118 os << "size: " << ds.data.size() << '\n' << "values: ";
0119 std::copy(ds.data.begin(), ds.data.end(), std::ostream_iterator<detset::value_type>(os, " "));
0120 }
0121
0122 void sanity_check(coll_type const& c) {
0123 check_outer_collection_order(c);
0124 for (coll_type::const_iterator i = c.begin(), e = c.end(); i != e; ++i) {
0125
0126
0127 check_inner_collection_order(*i);
0128 }
0129 }
0130
0131 void check_ids(coll_type const& c) {
0132
0133 std::vector<det_id_type> all_ids;
0134 for (coll_type::const_iterator i = c.begin(), e = c.end(); i != e; ++i) {
0135 all_ids.push_back(i->id);
0136 }
0137 assert(c.size() == all_ids.size());
0138
0139 std::vector<det_id_type> nice_ids;
0140 c.getIds(nice_ids);
0141 assert(all_ids == nice_ids);
0142 }
0143
0144 void detsetTest() {
0145
0146 detset d;
0147 Value v1(1.1);
0148 Value v2(2.2);
0149 d.id = edm::det_id_type(3);
0150 d.data.push_back(v1);
0151 d.data.push_back(v2);
0152 std::sort(d.data.begin(), d.data.end());
0153 check_inner_collection_order(d);
0154
0155 }
0156
0157 namespace {
0158 template <typename T>
0159 struct DSVGetter : edm::EDProductGetter {
0160 DSVGetter() : edm::EDProductGetter(), prod_(nullptr) {}
0161 WrapperBase const* getIt(ProductID const&) const override { return prod_; }
0162
0163 std::optional<std::tuple<edm::WrapperBase const*, unsigned int>> getThinnedProduct(ProductID const&,
0164 unsigned int) const override {
0165 return std::nullopt;
0166 }
0167
0168 void getThinnedProducts(ProductID const& pid,
0169 std::vector<WrapperBase const*>& wrappers,
0170 std::vector<unsigned int>& keys) const override {}
0171
0172 edm::OptionalThinnedKey getThinnedKeyFrom(ProductID const&, unsigned int, ProductID const&) const override {
0173 return std::monostate{};
0174 }
0175
0176 unsigned int transitionIndex_() const override { return 0U; }
0177
0178 edm::Wrapper<T> const* prod_;
0179 };
0180 }
0181
0182 void refTest() {
0183 coll_type c;
0184 detset d3;
0185 Value v1(1.1);
0186 Value v2(2.2);
0187 d3.id = edm::det_id_type(3);
0188 d3.data.push_back(v1);
0189 d3.data.push_back(v2);
0190 c.insert(d3);
0191 detset d1;
0192 Value v1a(4.1);
0193 Value v2a(3.2);
0194 d1.id = edm::det_id_type(1);
0195 d1.data.push_back(v1a);
0196 d1.data.push_back(v2a);
0197 c.insert(d1);
0198 c.post_insert();
0199
0200 auto pC = std::make_unique<coll_type>(c);
0201 edm::Wrapper<coll_type> wrapper(std::move(pC));
0202 DSVGetter<coll_type> theGetter;
0203 theGetter.prod_ = &wrapper;
0204
0205 typedef edm::Ref<coll_type, detset> RefDetSet;
0206 typedef edm::Ref<coll_type, Value> RefDet;
0207
0208 {
0209 RefDetSet refSet(edm::ProductID(1, 1), 0, &theGetter);
0210 assert(!(d1 < *refSet) && !(*refSet < d1));
0211 }
0212 {
0213 RefDetSet refSet(edm::ProductID(1, 1), 1, &theGetter);
0214 assert(!(d3 < *refSet) && !(*refSet < d3));
0215 }
0216 {
0217 RefDet refDet(edm::ProductID(1, 1), RefDet::key_type(3, 0), &theGetter);
0218 assert(!(v1 < *refDet) && !(*refDet < v1));
0219 }
0220
0221 {
0222 TestHandle<coll_type> pc2(&c, ProductID(1, 1));
0223 RefDet refDet = makeRefToDetSetVector(pc2, det_id_type(3), c[3].data.begin());
0224 assert(!(v1 < *refDet) && !(*refDet < v1));
0225 }
0226
0227 try {
0228
0229 TestHandle<coll_type> pc2(&c, ProductID(1, 1));
0230 RefDet refDet = makeRefToDetSetVector(pc2, det_id_type(12), c[3].data.begin());
0231
0232 assert("Failed to throw required exception" == 0);
0233 } catch (edm::Exception const& x) {
0234
0235
0236 assert(x.categoryCode() == edm::errors::InvalidReference);
0237 }
0238
0239 try {
0240
0241 TestHandle<coll_type> pc2(&c, ProductID(1, 1));
0242 RefDet refDet = makeRefToDetSetVector(pc2, det_id_type(1), c[3].data.begin());
0243
0244 assert("Failed to throw required exception" == 0);
0245 } catch (edm::Exception const& x) {
0246
0247
0248 assert(x.categoryCode() == edm::errors::InvalidReference);
0249 }
0250 }
0251
0252 void work() {
0253 detsetTest();
0254 refTest();
0255
0256 coll_type c1;
0257 c1.post_insert();
0258 sanity_check(c1);
0259 assert(c1.size() == 0);
0260 assert(c1.empty());
0261
0262 coll_type c2(c1);
0263 assert(c2.size() == c1.size());
0264 sanity_check(c2);
0265 coll_type c;
0266 sanity_check(c);
0267 {
0268 detset d;
0269 Value v1(1.1);
0270 Value v2(2.2);
0271 d.id = edm::det_id_type(3);
0272 d.data.push_back(v1);
0273 d.data.push_back(v2);
0274 c.insert(d);
0275 c.post_insert();
0276 }
0277 sanity_check(c);
0278 assert(c.size() == 1);
0279 {
0280 detset d;
0281 Value v1(4.1);
0282 Value v2(3.2);
0283 d.id = edm::det_id_type(1);
0284 d.data.push_back(v1);
0285 d.data.push_back(v2);
0286 c.insert(d);
0287 c.post_insert();
0288 }
0289 sanity_check(c);
0290 assert(c.size() == 2);
0291
0292 {
0293 detset d;
0294 Value v1(1.1);
0295 Value v2(1.2);
0296 Value v3(2.2);
0297 d.id = edm::det_id_type(10);
0298 d.data.push_back(v3);
0299 d.data.push_back(v2);
0300 d.data.push_back(v1);
0301 c.insert(d);
0302 c.post_insert();
0303 }
0304 sanity_check(c);
0305 assert(c.size() == 3);
0306
0307 coll_type another;
0308 c.swap(another);
0309 assert(c.empty());
0310 assert(another.size() == 3);
0311 sanity_check(c);
0312 sanity_check(another);
0313
0314 c.swap(another);
0315 assert(c.size() == 3);
0316
0317 {
0318
0319 coll_type::iterator i = c.find(edm::det_id_type(11));
0320 assert(i == c.end());
0321
0322 coll_type::const_iterator ci = static_cast<coll_type const&>(c).find(edm::det_id_type(11));
0323 assert(ci == c.end());
0324 }
0325 {
0326
0327 coll_type::iterator i = c.find(edm::det_id_type(10));
0328 assert(i != c.end());
0329 assert(i->id == 10);
0330 assert(i->data.size() == 3);
0331 }
0332
0333 {
0334
0335 try {
0336 coll_type::reference r = c[edm::det_id_type(100)];
0337 assert("Failed to throw required exception" == 0);
0338 assert(is_null(&r));
0339 } catch (edm::Exception const& x) {
0340
0341 assert(x.categoryCode() == edm::errors::InvalidReference);
0342 } catch (...) {
0343 assert("Failed to throw correct exception type" == 0);
0344 }
0345 }
0346
0347 {
0348
0349 try {
0350 coll_type::const_reference r = static_cast<coll_type const&>(c)[edm::det_id_type(100)];
0351 assert("Failed to throw required exception" == 0);
0352 assert(is_null(&r));
0353 } catch (edm::Exception const& x) {
0354
0355 assert(x.categoryCode() == edm::errors::InvalidReference);
0356 } catch (...) {
0357 assert("Failed to throw correct exception type" == 0);
0358 }
0359 }
0360 {
0361
0362 coll_type const& rc = c;
0363 coll_type::const_reference r = rc[3];
0364 assert(r.id == edm::det_id_type(3));
0365 assert(r.data.size() == 2);
0366
0367 coll_type::reference r2 = c[3];
0368 assert(r2.id == edm::det_id_type(3));
0369 assert(r2.data.size() == 2);
0370 }
0371
0372 {
0373
0374
0375 coll_type::size_type oldsize = c.size();
0376 coll_type::reference r = c.find_or_insert(edm::det_id_type(17));
0377 coll_type::size_type newsize = c.size();
0378 assert(newsize > oldsize);
0379 assert(newsize == (oldsize + 1));
0380 assert(r.id == edm::det_id_type(17));
0381 assert(r.data.size() == 0);
0382 r.data.push_back(Value(10.1));
0383 r.data.push_back(Value(9.1));
0384 r.data.push_back(Value(4.0));
0385 r.data.push_back(Value(4.0));
0386 c.post_insert();
0387 sanity_check(c);
0388 }
0389 {
0390
0391 unsigned int const numDetSets = 20;
0392 unsigned int const detSetSize = 14;
0393 std::vector<detset> v;
0394 for (unsigned int i = 0; i < numDetSets; ++i) {
0395 detset d(i);
0396 for (unsigned int j = 0; j < detSetSize; ++j) {
0397 d.data.push_back(Value(100 * i + 1.0 / j));
0398 }
0399 v.push_back(d);
0400 }
0401 assert(v.size() == numDetSets);
0402 coll_type c3(v);
0403 c3.post_insert();
0404 assert(v.size() == 0);
0405 assert(c3.size() == numDetSets);
0406 sanity_check(c3);
0407
0408 coll_type c4;
0409 c4 = c3;
0410 assert(c4.size() == numDetSets);
0411 sanity_check(c3);
0412 sanity_check(c4);
0413
0414 check_ids(c3);
0415 }
0416 }
0417
0418 int main() {
0419 int rc = -1;
0420 try {
0421 work();
0422 rc = 0;
0423 } catch (edm::Exception const& x) {
0424
0425 rc = 1;
0426 } catch (std::exception& x) {
0427
0428 rc = 3;
0429 } catch (...) {
0430
0431 rc = 2;
0432 }
0433 return rc;
0434 }