Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-08-06 09:38:31

0001 // -*- C++ -*-
0002 //
0003 // AnyReference.h is a part of ThePEG - Toolkit for HEP Event Generation
0004 // Copyright (C) 1999-2019 Leif Lonnblad
0005 // Copyright (C) 2010-2019 Simon Platzer
0006 //
0007 // ThePEG is licenced under version 3 of the GPL, see COPYING for details.
0008 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
0009 //
0010 #ifndef ThePEG_AnyReference_H
0011 #define ThePEG_AnyReference_H
0012 
0013 #include "ThePEG/Config/ThePEG.h"
0014 #include "Exception.h"
0015 
0016 namespace ThePEG {
0017 
0018   /**
0019    * AnyReference is inspired by boost::any to hold a reference to an
0020    * object of arbitrary type.
0021    */
0022   class AnyReference {
0023 
0024     struct ReferenceHolderBase {
0025 
0026       /**
0027        * The destructor.
0028        */
0029       virtual ~ReferenceHolderBase() {}
0030 
0031       /**
0032        * Return the type held.
0033        */
0034       virtual const std::type_info& type() const = 0;
0035 
0036       /**
0037        * Clone this reference holder.
0038        */
0039       virtual ReferenceHolderBase* clone() const = 0;
0040 
0041     };
0042 
0043     template<class T>
0044     struct ReferenceHolder 
0045       : public ReferenceHolderBase {
0046 
0047       /**
0048        * The reference held.
0049        */
0050       T& value;
0051 
0052       /**
0053        * Static member to initialize the reference.
0054        */
0055       static T& init() {
0056     static T v; return v;
0057       }
0058 
0059       /**
0060        * The default constructor
0061        */
0062       ReferenceHolder()
0063     : value(init()) {}
0064 
0065       /**
0066        * Construct from given reference.
0067        */
0068       explicit ReferenceHolder(T& v)
0069     : value(v) {}
0070 
0071       /**
0072        * Return the type held.
0073        */
0074       virtual const std::type_info& type() const {
0075     return typeid(T);
0076       }
0077 
0078       /**
0079        * Clone this reference holder.
0080        */
0081       virtual ReferenceHolderBase* clone() const {
0082     return new ReferenceHolder(*this);
0083       }
0084 
0085     };
0086 
0087     /**
0088      * The reference holder used.
0089      */
0090     ReferenceHolderBase* holder;
0091 
0092   public:
0093 
0094     /**
0095      * The default constructor
0096      */
0097     AnyReference()
0098       : holder(0) {}
0099 
0100     /**
0101      * The standard constructor
0102      */
0103     template<class T>
0104     AnyReference(T& v)
0105       : holder(new ReferenceHolder<T>(v)) {}
0106 
0107     /**
0108      * The copy constructor
0109      */
0110     AnyReference(const AnyReference& other)
0111       : holder(other.holder ? other.holder->clone() : 0) {}
0112 
0113     /**
0114      * The destructor.
0115      */
0116     ~AnyReference() {
0117         delete holder; holder = 0;
0118     }
0119 
0120   public:
0121 
0122     /**
0123      * Return the type held.
0124      */
0125     const std::type_info& type() const { return holder ? holder->type() : typeid(void); }
0126 
0127     /**
0128      * Return true, if no reference is held.
0129      */
0130     bool empty() const { return !holder; }
0131 
0132   public:
0133 
0134     /**
0135      * Swap the references held.
0136      */
0137     AnyReference& swap(AnyReference& other) { 
0138       std::swap(holder,other.holder); return *this;
0139     }
0140 
0141     /**
0142      * Assign from definite type
0143      */
0144     template<class T>
0145     AnyReference& operator=(T& v) {
0146       AnyReference(v).swap(*this);
0147       return *this;
0148     }
0149 
0150     /**
0151      * Assign from AnyReference
0152      */
0153     AnyReference& operator=(AnyReference other) {
0154       other.swap(*this);
0155       return *this;
0156     }
0157 
0158     /**
0159      * Reset to not keep track of any reference.
0160      */
0161     void reset() {
0162       delete holder; holder = 0;
0163     }
0164 
0165   public:
0166 
0167     /**
0168      * Extract the held reference.
0169      */
0170     template<class T>
0171     T& cast() const {
0172       if ( !empty() && type() == typeid(T) ) {
0173     return static_cast<ReferenceHolder<T>*>(holder)->value;
0174       }
0175       throw Exception() << "Bad cast in AnyReference" << Exception::abortnow;
0176       return ReferenceHolder<T>::init();
0177     }
0178 
0179   };
0180 
0181 }
0182 
0183 #endif // ThePEG_AnyReference_H