source: HiSusy/trunk/Delphes-3.0.0/external/fastjet/SharedPtr.hh @ 1

Last change on this file since 1 was 1, checked in by zerwas, 11 years ago

first import of structure, PYTHIA8 and DELPHES

File size: 12.7 KB
Line 
1#ifndef __FASTJET_SHARED_PTR_HH__
2#define __FASTJET_SHARED_PTR_HH__
3
4//STARTHEADER
5// $Id: SharedPtr.hh 2680 2011-11-12 17:12:05Z soyez $
6//
7// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
8//
9//----------------------------------------------------------------------
10// This file is part of FastJet.
11//
12//  FastJet is free software; you can redistribute it and/or modify
13//  it under the terms of the GNU General Public License as published by
14//  the Free Software Foundation; either version 2 of the License, or
15//  (at your option) any later version.
16//
17//  The algorithms that underlie FastJet have required considerable
18//  development and are described in hep-ph/0512210. If you use
19//  FastJet as part of work towards a scientific publication, please
20//  include a citation to the FastJet paper.
21//
22//  FastJet is distributed in the hope that it will be useful,
23//  but WITHOUT ANY WARRANTY; without even the implied warranty of
24//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25//  GNU General Public License for more details.
26//
27//  You should have received a copy of the GNU General Public License
28//  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
29//----------------------------------------------------------------------
30//ENDHEADER
31
32#include "fastjet/internal/base.hh"
33#include <cstdlib>  // for NULL!!!
34
35// for testing purposes, the following define makes it possible
36// for our SharedPtr simply to be derived from the STL TR1 one.
37// #define USETR1SHAREDPTR
38
39#ifdef USETR1SHAREDPTR
40#include <tr1/memory>
41#endif // USETR1SHAREDPTR
42
43FASTJET_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
44
45#ifdef USETR1SHAREDPTR
46
47/// @ingroup advanced_usage
48/// \class SharedPtr
49/// replaces our shared pointer with the TR1 one (for testing purpose)
50///
51/// for testing purposes, it can be useful to replace our home-made
52/// SharedPtr with the standard library one. Having a class derived
53/// from the standard one is way of arranging for this to happen.
54///
55/// The other way of working this is a template class with an
56/// internal typedef (http://bytes.com/topic/c/answers/60312-typedef-template)
57/// since templated typedefs don't work in standard C++
58///
59/// Note that some facilities that are present in the FastJet shared
60/// pointer (resetting use-count) are not handled by the TR1 shared
61/// pointer; and the FastJet SharedPtr has a different underlying data
62/// structure from the TR1 shared pointer, which prevents us from
63/// implementing some of TR1 features (notably assignment from shared
64/// pointers to a derived class).
65template<class T>
66class SharedPtr : public std::tr1::shared_ptr<T> {
67public:
68  SharedPtr() : std::tr1::shared_ptr<T>() {}
69  SharedPtr(T * t) : std::tr1::shared_ptr<T>(t) {}
70  SharedPtr(const SharedPtr<T> & t) : std::tr1::shared_ptr<T>(t) {}
71  // for some reason operator() doesn't get inherited
72  inline operator bool() const {return (this->get()!=NULL);}
73  /// return the pointer we're pointing to 
74  T* operator ()() const{
75    return this->get(); // automatically returns NULL when out-of-scope
76  }
77};
78
79
80#else // USETR1SHAREDPTR
81
82/**
83 * @ingroup advanced_usage
84 * \class SharedPtr
85 * an implementation of C++0x shared pointers (or boost's)
86 *
87 * this class implements a smart pointer, based on the shared+ptr
88 * proposal. A description of shared_ptr can be found in Section 2.2.3
89 * of the first C++ Technical Report (TR1)
90 *   http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1745.pdf
91 * or, alternatively, on the Boost C++ library website at
92 *   http://www.boost.org/doc/libs/1_42_0/libs/smart_ptr/shared_ptr.htm
93 *
94 * Our implementation is compatible with both of these apart from a
95 * series of members and functions that have not been implemented:
96 *  - conversion from weak and auto pointers
97 *  - support for deleters and allocators
98 *  - static, constant and dynamic casts
99 *  - constructor and assignment sharing ownership with a shared
100 *    pointer r but storing a different pointer than r (needed for the
101 *    previous item)
102 * In the last 2 cases, their implementation would require storing two
103 * pointers for every copies of the shared pointer, while our
104 * implementation only needs one. We did not implement then since we
105 * want to limit as much as possible memory and time consumption, and
106 * can easily avoid (at least for our needs so far) the casts.
107 *
108 * We also add the possibility to force an update of the count.
109 *
110 * The class has been tested against the existing boost (v1.42)
111 * implementation (for the parts that we have implemented).
112 */
113template<class T>
114class SharedPtr{
115public:
116  /// forward declaration of the counting container
117  class __SharedCountingPtr;
118
119  /// default ctor
120  SharedPtr() : _ptr(NULL){}
121 
122  /// initialise with the main data
123  /// \param  t  : the object we want a smart pointer to
124  template<class Y> explicit SharedPtr(Y* ptr){
125    _ptr = new __SharedCountingPtr(ptr);
126  }
127 
128  /// overload the copy ctor so that it updates count
129  /// \param  share : the object we want to copy
130  SharedPtr(SharedPtr const & share) : _ptr(share._get_container()){
131    if (_ptr!=NULL) ++(*_ptr);
132  }
133  // old version
134  //  SharedPtr(SharedPtr const & share) : _ptr(NULL){
135  //    reset(share);
136  //  }
137   
138  // will not work with the current structure
139  // /// overload the copy ctor so that it updates count
140  // /// \param  share : the object we want to copy
141  // template<class Y> SharedPtr(SharedPtr<Y> const & share) : _ptr(NULL){
142  //   reset(share);
143  // }
144
145  /// default dtor
146  ~SharedPtr(){
147    // make sure the object has been allocated
148    if (_ptr==NULL) return;
149
150    _decrease_count();
151  }
152
153  /// reset the pointer to default value (NULL)
154  void reset(){
155    // // if we already are pointing to sth, be sure to decrease its count
156    // if (_ptr!=NULL) _decrease_count();
157    // _ptr = NULL;
158    SharedPtr().swap(*this);
159  }
160 
161  // will not work with the current structure
162  /// reset from a pointer
163  template<class Y> void reset(Y * ptr){
164    // // if we already are pointing to sth, be sure to decrease its count
165    // if (_ptr!=NULL) _decrease_count();
166    //
167    // _ptr = new __SharedCountingPtr(ptr);
168    SharedPtr(ptr).swap(*this);
169  }
170
171  // not part of the standard
172  /// do a smart copy
173  /// \param  share : the object we want to copy
174  /// Q? Do we need a non-template<Y> version as for the ctor and the assignment?
175  template<class Y> void reset(SharedPtr<Y> const & share){
176  //void reset(SharedPtr const & share){
177    // if we already are pointing to sth, be sure to decrease its count
178    if (_ptr!=NULL){
179      // in the specific case where we're having the same
180      // share,reset() has actually no effect. However if *this is the
181      // only instance still alive (implying share==*this) bringing
182      // the count down to 0 and deleting the object will not have the
183      // expected effect. So we just avoid that situation explicitly
184      if (_ptr == share._get_container()) return;
185   
186      _decrease_count();
187    }
188   
189    // Watch out: if share is empty, construct an empty shared_ptr
190   
191    // copy the container
192    _ptr = share._get_container();  // Note: automatically set it to NULL if share is empty
193   
194    if (_ptr!=NULL) ++(*_ptr);
195  }
196 
197  /// overload the = operator so that it updates count
198  /// \param  share : the object we want to copy
199  SharedPtr& operator=(SharedPtr const & share){
200    reset(share);
201    return *this;
202  }
203 
204  /// overload the = operator so that it updates count
205  /// \param  share : the object we want to copy
206  template<class Y> SharedPtr& operator=(SharedPtr<Y> const & share){
207    reset(share);
208    return *this;
209  }
210 
211  /// return the pointer we're pointing to 
212  T* operator ()() const{
213    if (_ptr==NULL) return NULL;
214    return _ptr->get(); // automatically returns NULL when out-of-scope
215  }
216 
217  /// indirection, get a reference to the stored pointer
218  ///
219  /// !!! WATCH OUT
220  /// It fails to check the requirement that the stored pointer must
221  /// not be NULL!!  So you need explicitly to check the validity in
222  /// your code
223  inline T& operator*() const{
224    return *(_ptr->get());
225  }
226
227  /// indirection, get the stored pointer
228  ///
229  /// !!! WATCH OUT
230  /// It fails to check the requirement that the stored pointer must
231  /// not be NULL!!  So you need explicitly to check the validity in
232  /// your code
233  inline T* operator->() const{
234    if (_ptr==NULL) return NULL;
235    return _ptr->get();
236  } 
237
238  /// get the stored pointer
239  inline T* get() const{
240    if (_ptr==NULL) return NULL;
241    return _ptr->get();
242  }
243
244  /// check if the instance is unique
245  inline bool unique() const{
246    return (use_count()==1);
247  }
248
249  /// return the number of counts
250  inline long use_count() const{
251    if (_ptr==NULL) return 0;
252    return _ptr->use_count(); // automatically returns NULL when out-of-scope
253  }
254
255  /// conversion to bool
256  /// This will allow you to use the indirection nicely
257  inline operator bool() const{
258    return (get()!=NULL);
259  }
260
261  /// exchange the content of the two pointers
262  inline void swap(SharedPtr & share){
263    __SharedCountingPtr* share_container = share._ptr;
264    share._ptr = _ptr;
265    _ptr = share_container;
266  }
267
268  /// force the count to be set to a specified value
269  ///   \param count   the value that we need to reset to
270  void set_count(const long & count){
271    if (_ptr==NULL) return;
272    _ptr->set_count(count);
273  }
274
275  /**
276   * \if internal_doc
277   * \class __SharedCountingPtr
278   * A reference-counting pointer
279   *
280   * This is implemented as a container for that pointer together with
281   * reference counting.
282   * The pointer is deleted when the number of counts goes to 0;
283   * \endif
284   */
285  class __SharedCountingPtr{
286  public:
287    /// default ctor
288    __SharedCountingPtr() : _ptr(NULL), _count(0){}
289   
290    /// ctor with initialisation
291    template<class Y> explicit __SharedCountingPtr(Y* ptr) : _ptr(ptr), _count(1){}
292   
293    /// default dtor
294    ~__SharedCountingPtr(){ 
295      // force the deletion of the object we keep track of
296      if (_ptr!=NULL){ delete _ptr;}
297    }
298
299    /// return a pointer to the object
300    inline T* get() const {return _ptr;}
301
302    /// return the count
303    inline long use_count() const {return _count;}
304
305    /// prefix increment operator
306    inline long operator++(){return ++_count;}
307
308    /// prefix decrement operator
309    inline long operator--(){return --_count;}
310
311    /// postfix increment operator
312    /// The "dummy" int argument is just a C++ trick to differentiate
313    /// it from the prefix increment
314    inline long operator++(int){return _count++;}
315
316    /// postfix decrement operator
317    /// The "dummy" int argument is just a C++ trick to differentiate
318    /// it from the prefix decrement
319    inline long operator--(int){return _count--;}
320
321    /// force the count to be set to a specified value
322    ///   \param count   the value that we ned to reset to
323    void set_count(const long & count){
324      _count = count;
325    }
326
327  private:
328    T *_ptr;              ///< the pointer we're counting the references to
329    long _count;  ///< the number of references
330  };
331
332private:
333  /// return the common container
334  inline __SharedCountingPtr* _get_container() const{
335    return _ptr;
336  }
337
338  /// decrease the pointer count and support deletion
339  /// Warning: we don't test that the pointer is allocated
340  ///          This can be dangerous if we have explicitly reset the
341  ///          count.  Generally speaking, if the count goes negative
342  ///          after _ptr has been effectively deleted, this is going
343  ///          to lead to a segmentation fault. But, if in the course
344  ///          of the deletion of _ptr, the deletion of its pointer
345  ///          (_ptr::_ptr, i.e. the real data we're storing) makes
346  ///          the counts to become negative, this is going to pass
347  ///          smoothly.
348  void _decrease_count(){
349    // decrease the count
350    (*_ptr)--;
351   
352    // if no one else is using it, free the allocated memory
353    if (_ptr->use_count()==0)
354      delete _ptr; // that automatically deletes the object itself
355  }
356
357  // the real info
358  __SharedCountingPtr *_ptr;
359};
360
361
362/// comparison: equality
363template<class T,class U>
364inline bool operator==(SharedPtr<T> const & t, SharedPtr<U> const & u){
365  return t.get() == u.get();
366}
367
368/// comparison: difference
369template<class T,class U>
370inline bool operator!=(SharedPtr<T> const & t, SharedPtr<U> const & u){
371  return t.get() != u.get();
372}
373
374/// comparison: orgering
375template<class T,class U>
376inline bool operator<(SharedPtr<T> const & t, SharedPtr<U> const & u){
377  return t.get() < u.get();
378}
379
380/// swapping
381template<class T>
382inline void swap(SharedPtr<T> & a, SharedPtr<T> & b){
383  return a.swap(b);
384}
385
386/// getting the pointer
387template<class T>
388inline T* get_pointer(SharedPtr<T> const & t){
389  return t.get();
390}
391
392#endif // USETR1SHAREDPTR
393
394FASTJET_END_NAMESPACE      // defined in fastjet/internal/base.hh
395
396#endif   // __FASTJET_SHARED_PTR_HH__
Note: See TracBrowser for help on using the repository browser.