Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-03-17 10:49:31

0001 #include "DataFormats/Common/interface/OwnVector.h"
0002 #include "DataFormats/Common/interface/PtrVector.h"
0003 #include "DataFormats/Common/interface/RefVector.h"
0004 #include "FWCore/Utilities/interface/Exception.h"
0005 
0006 #include "boost/range.hpp"
0007 
0008 #include <algorithm>
0009 #include <cassert>
0010 #include <iostream>
0011 #include <vector>
0012 
0013 struct Dummy {
0014   Dummy() : id() {}
0015   Dummy(int i) : id(i) {}
0016   Dummy* clone() const { return new Dummy(*this); }
0017   int id;
0018   bool operator==(int const& i) const { return id == i; }
0019 };
0020 typedef std::vector<Dummy> Coll;
0021 Coll dummies_;
0022 
0023 template <typename T>
0024 void testFill(T& r) {
0025   for (int i = 0; i < 12; ++i) {
0026     r.push_back(typename T::value_type(i));
0027   }
0028 }
0029 template <>
0030 void testFill<edm::RefVector<Coll> >(edm::RefVector<Coll>& r) {
0031   edm::TestHandle<Coll> h(&dummies_, edm::ProductID(1));
0032   for (int i = 0; i < 12; ++i) {
0033     r.push_back(edm::Ref<Coll>(h, i));
0034   }
0035 }
0036 template <>
0037 void testFill<edm::PtrVector<Dummy> >(edm::PtrVector<Dummy>& r) {
0038   edm::TestHandle<Coll> h(&dummies_, edm::ProductID(1));
0039   for (int i = 0; i < 12; ++i) {
0040     r.push_back(edm::Ptr<Dummy>(h, i));
0041   }
0042 }
0043 //template<>
0044 //void testFill<edm::OwnVector<Dummy> >(edm::OwnVector<Dummy> &r) {
0045 //    for(int i = 0; i < 12; ++i) { r.push_back(std::make_unique<Dummy>(i)); }
0046 //}
0047 
0048 bool operator==(edm::Ref<Coll> const& ref, int i) { return (int(ref.key()) == i) && (ref->id == i); }
0049 bool operator==(edm::Ptr<Dummy> const& ref, int i) { return (int(ref.key()) == i) && (ref->id == i); }
0050 std::ostream& operator<<(std::ostream& o, Dummy const& v) {
0051   o << "Dummy(" << v.id << ")";
0052   return o;
0053 }
0054 std::ostream& operator<<(std::ostream& o, edm::Ref<Coll> const& v) {
0055   o << "DummyRef(" << v.key() << " -> " << v->id << ")";
0056   return o;
0057 }
0058 std::ostream& operator<<(std::ostream& o, edm::Ptr<Dummy> const& v) {
0059   o << "DummyPtr(" << v.key() << " -> " << v->id << ")";
0060   return o;
0061 }
0062 
0063 template <typename R>
0064 void testEquals(typename R::value_type const& v, int i, char const* name) {
0065   if (!(v == i)) {
0066     std::cout << "Error: " << v << " != " << i << " for " << typeid(R).name() << " at " << name << std::endl;
0067   }
0068 }
0069 
0070 template <typename R>
0071 void test_read_value_fb(R const& r) {
0072   typename R::value_type v1 = r.front();
0073   typename R::value_type v2 = r.back();
0074   testEquals<R>(v1, 4, __func__);
0075   testEquals<R>(v2, 7, __func__);
0076 }
0077 
0078 template <typename R>
0079 void test_read_value_brackets(R const& r) {
0080   typename R::value_type v1 = r[0];
0081   typename R::value_type v2 = r[3];
0082   testEquals<R>(v1, 4, __func__);
0083   testEquals<R>(v2, 7, __func__);
0084 }
0085 
0086 template <typename R>
0087 void test_read_iter(R const& r) {
0088   int check = 4;
0089   for (typename R::const_iterator it = r.begin(), ed = r.end(); it != ed; ++it, ++check) {
0090     typename R::value_type v = *it;
0091     testEquals<R>(v, check, __func__);
0092   }
0093 }
0094 
0095 template <typename R>
0096 void test_size(R const& r) {
0097   size_t i = r.size();
0098   if (i != 4)
0099     std::cout << "Error: r.size() = " << i << " != 4 for " << typeid(R).name() << " at " << __func__ << std::endl;
0100 }
0101 
0102 template <typename R>
0103 void test_empty(R const& r) {
0104   bool b = r.empty();
0105   if (b)
0106     std::cout << "Error: r.empty() is true for " << typeid(R).name() << " at " << __func__ << std::endl;
0107 }
0108 
0109 struct DummySorter {
0110   bool operator()(Dummy const& t1, Dummy const& t2) const { return t1.id > t2.id; }
0111   bool operator()(edm::Ref<Coll> const& t1, edm::Ref<Coll> const& t2) const { return t1->id > t2->id; }
0112   bool operator()(edm::Ptr<Dummy> const& t1, edm::Ptr<Dummy> const& t2) const { return t1->id > t2->id; }
0113 };
0114 template <typename R>
0115 void test_sort(R r) {
0116   //std::cout << "Check sort for " << typeid(R).name() << std::endl;
0117   //std::cout << "Before sort: " << std::endl;
0118   assert(!std::is_sorted(r.begin(), r.end(), DummySorter()));
0119   //for(typename R::const_iterator it = r.begin(), ed = r.end(); it != ed; ++it) { std::cout << " - " << *it << std::endl; }
0120   std::sort(r.begin(), r.end(), DummySorter());
0121   //std::cout << "After sort: " << std::endl;
0122   //for(typename R::const_iterator it = r.begin(), ed = r.end(); it != ed; ++it) { std::cout << " - " << *it << std::endl; }
0123   //std::cout << "End check " << std::endl;
0124   if (!std::is_sorted(r.begin(), r.end(), DummySorter())) {
0125     std::cout << "Sort for " << typeid(R).name() << " compiles but doesn't sort!" << std::endl;
0126   }
0127 }
0128 
0129 template <typename T>
0130 void test_subrange(T t) {
0131   typedef boost::sub_range<T const> R;
0132   testFill(t);
0133   R r(t.begin() + 4, t.begin() + 8);
0134   test_empty(r);
0135   test_size(r);
0136   test_read_iter(r);
0137   test_read_value_fb(r);
0138   test_read_value_brackets(r);
0139 }
0140 
0141 template <typename T>
0142 void test_itrange(T t) {
0143   typedef boost::iterator_range<typename T::const_iterator> R;
0144   testFill(t);
0145   R r(t.begin() + 4, t.begin() + 8);
0146   test_empty(r);
0147   test_size(r);
0148   test_read_iter(r);
0149   test_read_value_fb(r);
0150   test_read_value_brackets(r);
0151   test_sort(r);
0152 }
0153 
0154 template <typename T>
0155 void test_const_itr_is_const(T const& t) {
0156   typename T::const_iterator itr = t.begin();
0157   *itr = t[0];
0158 }
0159 
0160 template <typename T>
0161 void test(T t) {
0162   testFill(t);
0163   test_const_itr_is_const(t);
0164   test_sort(t);
0165   test_itrange(t);
0166   test_subrange(t);
0167 }
0168 
0169 using namespace std;
0170 using namespace edm;
0171 
0172 #define DISABLE_SORT_IT(Y) \
0173   template <>              \
0174   void test_sort<boost::iterator_range<Y::const_iterator> >(boost::iterator_range<Y::const_iterator>) {}
0175 #define DISABLE_SORT_SUB(Y) \
0176   template <>               \
0177   void test_sort<boost::sub_range<Y const> >(boost::sub_range<Y const>) {}
0178 #define DISABLE_SORT_BARE(Y) \
0179   template <>                \
0180   void test_sort<Y>(Y) {}
0181 #define DISABLE_SORT_ALL(Y) \
0182   DISABLE_SORT_IT(Y)        \
0183   DISABLE_SORT_SUB(Y)
0184 #define DISABLE_CONST_ITR_IS_CONST(Y) \
0185   template <>                         \
0186   void test_const_itr_is_const<Y>(Y const&) {}
0187 
0188 // Comment out to check that std::sort does not compile for boost ranges of const X
0189 DISABLE_SORT_ALL(std::vector<Dummy>)
0190 DISABLE_SORT_ALL(edm::OwnVector<Dummy>)
0191 DISABLE_SORT_ALL(edm::PtrVector<Dummy>)
0192 DISABLE_SORT_ALL(edm::RefVector<Coll>)
0193 // Comment out to check that you can't assign a value to the '*' of a const_iterator
0194 DISABLE_CONST_ITR_IS_CONST(std::vector<Dummy>)
0195 DISABLE_CONST_ITR_IS_CONST(edm::OwnVector<Dummy>)
0196 DISABLE_CONST_ITR_IS_CONST(edm::PtrVector<Dummy>)
0197 DISABLE_CONST_ITR_IS_CONST(edm::RefVector<Coll>)
0198 // Comment out to check that std::sort doesn't compile or runs properly
0199 DISABLE_SORT_BARE(edm::PtrVector<Dummy>)
0200 DISABLE_SORT_BARE(edm::RefVector<Coll>)
0201 
0202 int main(int, char**) try {
0203   dummies_.clear();
0204   for (int i = 0; i < 12; ++i)
0205     dummies_.push_back(Dummy(i));
0206   test(vector<Dummy>());
0207   test(RefVector<Coll>());
0208   test(PtrVector<Dummy>());
0209   test(OwnVector<Dummy>());
0210   return 0;
0211 } catch (cms::Exception const& e) {
0212   std::cerr << e.explainSelf() << std::endl;
0213   return 1;
0214 } catch (std::exception const& e) {
0215   std::cerr << e.what() << std::endl;
0216   return 1;
0217 }