/cvmfs/atlas.cern.ch/repo/sw/ASG/AnalysisBase/2.4.28/AthContainers/AthContainers/DataList.h File Reference

An STL list of pointers that by default owns its pointed-to elements. More...

#include <list>
#include <typeinfo>
#include <functional>
#include <iostream>
#include <algorithm>
#include <iterator>
#include <boost/static_assert.hpp>
#include <boost/type_traits.hpp>
#include <boost/iterator/iterator_adaptor.hpp>
#include "SGTools/BaseInfo.h"
#include "SGTools/DataBucketTraitFwd.h"
#include "SGTools/ClassName.h"
#include "AthContainers/OwnershipPolicy.h"
#include "AthContainers/exceptions.h"
#include "AthContainers/tools/DVLNoBase.h"
#include "AthContainers/tools/DVLInfo.h"
#include "AthContainers/tools/DVLDataBucket.h"
#include "AthContainers/tools/DVLCast.h"
#include "AthContainers/tools/DVLIterator.h"
#include "AthContainers/tools/DVL_iter_swap.h"
#include "AthContainers/tools/DVL_algorithms.h"
#include "AthContainers/tools/ElementProxy.h"
#include "AthContainers/tools/IsMostDerivedFlag.h"
#include "AthLinks/tools/selection_ns.h"
#include "AthContainers/DataList.icc"

Go to the source code of this file.

Classes

struct  DataListBase< T >
 Derivation information for DataList. More...
class  DataList< T, BASE >
 Derived DataList<T>. More...
class  DataList< T, DataModel_detail::NoBase >
 Base specialization for DataList<T>. More...
class  ClassName< DataList< T > >
 Specialization of ClassName for DataList. More...
class  DataList< T, BASE >
 Derived DataList<T>. More...
struct  SG::DataBucketTrait< DataList< T >, U >
 Metafunction to find the proper DataBucket class for T. More...

Namespaces

namespace  SG
 

Constructor from a payload object.


Defines

#define HAVE_CONSTDATAVECTOR
#define DATALIST_BASE(T, BASE)
 Declare base class info to DataList. Single, non-virtual derivation.
#define DATALIST_VIRTBASES1(T, B1)
 Declare base class info to DataList. Single, virtual derivation.
#define DATALIST_VIRTBASES2(T, B1, B2)
 Declare base class info to DataList. Multiple derivation.
#define DATALIST_VIRTBASES3(T, B1, B2, B3)
 Declare base class info to DataList. Multiple derivation.

Functions

template<class DL >
void test2_assignelement1 ()
template<class T >
bool operator== (const DataList< T > &a, const DataList< T > &b)
 List equality comparison.
template<class T >
bool operator!= (const DataList< T > &a, const DataList< T > &b)
 Based on operator==.
template<class T >
bool operator< (const DataList< T > &a, const DataList< T > &b)
 List ordering relation.
template<class T >
bool operator> (const DataList< T > &a, const DataList< T > &b)
 Based on operator<.
template<class T >
bool operator<= (const DataList< T > &a, const DataList< T > &b)
 Based on operator<.
template<class T >
bool operator>= (const DataList< T > &a, const DataList< T > &b)
 Based on operator<.
template<class T >
void swap (DataList< T > &a, DataList< T > &b)
 See DataList<T, BASE>::swap().

Detailed Description

An STL list of pointers that by default owns its pointed-to elements.

Author:
Srini Rajagopalan, Sebastien Binet - ATLAS Collaboration
Date:
February 2006; rewritten from earlier version. For further information, see <https://twiki.cern.ch/twiki/bin/view/Atlas/DataVector>

A DataList<T> acts like a std::list<T*>, except that it can optionally manage the memory that it contains. The constructors take an (optional) extra argument, which can be either SG::OWN_ELEMENTS or SG::VIEW_ELEMENTS (defaulting to SG::OWN_ELEMENTS except for a copy constructor). This tells whether the DataList owns its contained elements or not.

If a DataList owns its elements, then they are deleted when the container itself is. Further, they are deleted by actions which erase elements from the container (i.e.: erase(), pop_back() ). A replacement (such as (*l.front()) = new T; ) will result in the old element being deleted and the container taking ownership of the new element. It is an error to assign directly between two owning containers ( (*list1.front()) = (*list2.front());).

Beware of ownership issues when modify a DataList . Obviously you should not delete explicitly a DataList element (because this is already taken care of by this object). A DataList should never have two elements pointing to the same object. This may seem obvious but certain STL algorithms (eg: remove_if ) may leave a DataList with two copies of the same element in the "left-over" range. To avoid a crash when clearing the list (eg: in the destructor we have introduced a $ n\log n $ helper function that searches and removes duplicates in the DataList . This is used by the destructor by clear() and by erase(first, last). As this may change in the future to improve performance, do not rely on this functionality and do avoid introducing duplicated elements in a DataList .

All these cautions do not apply when a DataList it is created with the flag SG::VIEW_ELEMENTS (see enum OwnershipPolicy) and hence does not own its elements. This is typically used to have DataList elements allocated by DataPool. Otherwise consider the cleaner alternative of using a list<T*>.

The interface for DataList should be mostly compatible with that of std::list. There are a few differences which should not make much difference in practice. For example, methods which would return a reference return a proxy object instead. Also value_type is used instead of const_reference; this is justified by the fact that the elements are always pointers.

Note that algorithms which modify their range may not work correctly if the container owns its contents. Specializations that work properly for DataList are available for some algorithms. These include:

There are a few other additions to the standard std::list interface.

Note that since DataList<T> has an element type of T*, it is not possible to directly insert a const T*. If you want to do that, see ConstDataList. (In some cases, such as if the destination container is not being recorded in StoreGate, it may be more appropriate to simply use a std::list<const T*>.) Don't just use a const_cast!

Finally, DataList's may inherit from one another. If you have class D which derives from class B, you can set things up so that DataList<D> derives from DataList<B>. This allows you do to the same sort of conversions on the DataList's as on the element pointers themselves. The key to doing this is to add the declaration

   DATALIST_BASE (D, B);

before using DataList<D>. A few caveats about doing this. The pointers are actually stored in the base DataList instance, and the type that stdcont returns will reflect this. For example, in the example given above, DataList<D>::stdcont() will return a reference to std::list<B*>. Second, in order to preserve the invariant that a DataList<D> contains only elements that actually derive from D, while at the same time not requiring that the contained objects be polymorphic, there is a restriction that you cannot insert into a DataList if you're not referring to it as the most derived type (even if such an insertion would not actually break the invariant). This is implemented as a runtime check.

Example:

   DataList<D> ld;
   ld.push_back (new D);  // This is ok.
   ld.push_back (new B);  // This will give a compilation error
                             (it would break the invariant).
   DataList<B>& lb = ld;
   lb.push_back (new B);  // This will give a run-time error
                             (it breaks the invariant).
   lb.push_back (new D);  // This will also give a run-time error.
                             (It's actually ok, but there's no good way
                             to distinguish it from the previous case.)

Note also this (related to a common atlas idiom). If we have the above, and also:

   class B_List : public DataList<B> { ... };
   class D_List : public DataList<D> { ... };

Then a D_List will be convertible to a DataList<B>, but _not_ to a B_List.

Multiple and virtual inheritance are also supported. In this case, use DATALIST_VIRTBASESn (where n is 1, 2, or 3) instead of DATALIST_BASE. Example: Given:

   class M { ... };
   class N : virtual public M { ... };
   class O : virtual public M { ... };
   class P : virtual public N, virtual public O { ... };

declare this with

   DATALIST_VIRTBASES1(N, M);
   DATALIST_VIRTBASES1(O, M);
   DATALIST_VIRTBASES2(P, N, O);

There is a restriction that there must be a unique base class that does not derive from anything else. For example, the diamond configuration above is ok, but this would not be:

   class L { ... };
   class M { ... };
   class N : virtual public M, virtual public L { ... };
   class O : virtual public M { ... };
   class P : virtual public N, virtual public O { ... };

   DATALIST_VIRTBASES2(N, M, L);
   DATALIST_VIRTBASES1(O, M);
   DATALIST_VIRTBASES2(P, N, O);

Note, however, that you don't have to tell DataList about the complete hierarchy; leaving the L out of DATALIST_VIRTBASES would work (you just wouldn't be able to convert to DataList<L> ).

If you use DATALIST_VIRTBASES, there is an additional time penalty to retrieve elements from the collection. This does not apply for DATALIST_BASES.

All applicable DATALIST_* macros must be visible at the point at which a DataList is instantiated. A confusing compilation error is likely to result otherwise. Note that this means that if you have the DATALIST_* macros within a container header file, then the header for the derived container must include the header for the base container. Be alert to this when converting existing code to use the inheritance scheme. For example, if class D2 derives from D which derives from B:

BList.h:

  #include "B.h"
  #include "DataList.h"
  typedef DataList<B> BVec;

DList.h:

  #include "D.h"
  #include "DataList.h"
  DATALIST_BASE(D,B);
  typedef DataList<D> DVec;

D2List.h:

  #include "D2.h"
  #include "DataList.h"
  #include "DList.h" // This is required
  DATALIST_BASE(D2,D);
  typedef DataList<D2> DVec;

Using DATALIST_BASE will also set up the corresponding SG::BaseInfo definitions, both for the vectors themselves and for the contained objects.


Define Documentation

#define DATALIST_BASE ( T,
BASE   ) 
Value:
template <> struct DataListBase<T>      \
{ typedef DataList<BASE> Base; };       \
SG_BASE(DataList<T>, DataList<BASE>); \
template struct DataList_detail::DVLEltBaseInit<T>

Declare base class info to DataList. Single, non-virtual derivation.

DATALIST_BASE(D, B) says that D derives non-virtually from B.

This macro creates an appropriate specialization of DataListBase.

#define DATALIST_VIRTBASES1 ( T,
B1   ) 
Value:
template <> struct DataListBase<T>                  \
{ typedef DataList_detail::VirtBases<B1> Base; };   \
SG_BASES1(DataList<T>, SG_VIRTUAL(DataList<B1>)); \
template struct DataList_detail::DVLEltBaseInit<T>

Declare base class info to DataList. Single, virtual derivation.

DATALIST_VIRTBASES(D, B1) says that D derives virtually from B1.

This macro creates an appropriate specialization of DataListBase.

#define DATALIST_VIRTBASES2 ( T,
B1,
B2   ) 
Value:
template <> struct DataListBase<T>                    \
{ typedef DataList_detail::VirtBases<B1, B2> Base; }; \
SG_BASES2(DataList<T>, SG_VIRTUAL(DataList<B1>),      \
                       SG_VIRTUAL(DataList<B2>)); \
template struct DataList_detail::DVLEltBaseInit<T>

Declare base class info to DataList. Multiple derivation.

DATALIST_VIRTBASES(D, B1) says that D derives from both B1 and B2.

This macro creates an appropriate specialization of DataListBase.

#define DATALIST_VIRTBASES3 ( T,
B1,
B2,
B3   ) 
Value:
template <> struct DataListBase<T>                    \
{ typedef DataList_detail::VirtBases<B1, B2, B3> Base; }; \
SG_BASES3(DataList<T>, SG_VIRTUAL(DataList<B1>),          \
               SG_VIRTUAL(DataList<B2>),          \
               SG_VIRTUAL(DataList<B3>)); \
template struct DataList_detail::DVLEltBaseInit<T>

Declare base class info to DataList. Multiple derivation.

DATALIST_VIRTBASES(D, B1) says that D derives from all of B1, B2, and B3.

This macro creates an appropriate specialization of DataListBase.


Function Documentation

template<class T >
bool operator< ( const DataList< T > &  a,
const DataList< T > &  b 
) [inline]

List ordering relation.

Parameters:
a A DataList.
b A DataList of the same type as a.
Returns:
True if a is lexicographically less than b.

This is a total ordering relation. It is linear in the size of the lists. Comparisons are done on the pointer values of the elements.

See std::lexicographical_compare() for how the determination is made.

Parameters:
a A DataList.
b A DataList of the same type as x.
Returns:
True iff x is lexicographically less than y.

This is a total ordering relation. It is linear in the size of the lists. Comparisons are done on the pointer values of the elements.

See std::lexicographical_compare() for how the determination is made.

template<class T >
bool operator== ( const DataList< T > &  a,
const DataList< T > &  b 
) [inline]

List equality comparison.

Parameters:
a A DataList.
b A DataList of the same type as a.
Returns:
True if the size and elements of the lists are equal.

This is an equivalence relation. It is linear in the size of the lists. Lists are considered equivalent if their sizes are equal, and if corresponding elements compare equal.

Parameters:
a A DataList.
b A DataList of the same type as x.
Returns:
True iff the size and elements of the lists are equal.

This is an equivalence relation. It is linear in the size of the lists. Lists are considered equivalent if their sizes are equal, and if corresponding elements compare equal.

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 15 Apr 2017 for RootCore Packages by  doxygen 1.6.1