Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 12:54:51

0001 #ifndef CMSSW_mayown_ptr_H
0002 #define CMSSW_mayown_ptr_H
0003 
0004 #include <cassert>
0005 #include <cstring>
0006 
0007 // a smart pointer which may own
0008 // can be implemented trivially with shared_ptr
0009 // this is infinetely ligher
0010 // assume alignment > 2....
0011 
0012 template <typename T, int N = sizeof(T*)>
0013 class mayown_ptr {
0014 private:
0015   T const* p = nullptr;
0016 
0017   void markOwn() {
0018     if (nullptr == p)
0019       return;
0020     unsigned char buff[N];
0021     memcpy(buff, &p, N);
0022     assert((buff[N - 1] & 1) == 0);
0023     ++buff[N - 1];
0024     memcpy(&p, buff, N);
0025   }
0026 
0027 public:
0028   bool isOwn() const {
0029     unsigned char buff[N];
0030     memcpy(buff, &p, N);
0031     return 1 == (buff[N - 1] & 1);
0032   }
0033 
0034 private:
0035   T const* pointer() const {
0036     unsigned char buff[N];
0037     memcpy(buff, &p, N);
0038     buff[N - 1] &= 0xFE;
0039     assert((buff[N - 1] & 1) == 0);
0040     T const* np;
0041     memcpy(&np, buff, N);
0042     return np;
0043   }
0044 
0045   void destroy() {
0046     if (isOwn())
0047       delete const_cast<T*>(pointer());
0048   }
0049 
0050 public:
0051   explicit mayown_ptr(T* ip = nullptr) : p(ip) { markOwn(); }
0052   explicit mayown_ptr(T const& ip) : p(&ip) {}
0053   ~mayown_ptr() { destroy(); }
0054   mayown_ptr(mayown_ptr&) = delete;
0055   mayown_ptr(mayown_ptr&& rh) : p(rh.p) { rh.p = nullptr; }
0056   mayown_ptr& operator=(mayown_ptr&) = delete;
0057   mayown_ptr& operator=(mayown_ptr&& rh) {
0058     destroy();
0059     p = rh.p;
0060     rh.p = nullptr;
0061     return *this;
0062   }
0063 
0064   T const& operator*() const { return *pointer(); }
0065   T const* operator->() const { return pointer(); }
0066   T const* get() const { return pointer(); }
0067   T const* release() {
0068     auto np = pointer();
0069     p = nullptr;
0070     return np;
0071   }
0072   void reset() {
0073     destroy();
0074     p = nullptr;
0075   }
0076   void reset(T* ip) {
0077     destroy();
0078     p = ip;
0079     markOwn();
0080   }
0081   void reset(T const& ip) {
0082     destroy();
0083     p = &ip;
0084   }
0085   bool empty() const { return nullptr == p; }
0086 
0087   T const* raw() const { return p; }
0088 };
0089 
0090 template <typename T>
0091 bool operator==(mayown_ptr<T> const& rh, mayown_ptr<T> const& lh) {
0092   return rh.raw() == lh.raw();
0093 }
0094 template <typename T>
0095 bool operator<(mayown_ptr<T> const& rh, mayown_ptr<T> const& lh) {
0096   return rh.raw() < lh.raw();
0097 }
0098 
0099 #endif