File indexing completed on 2026-08-06 09:38:31
0001
0002
0003
0004
0005
0006
0007
0008
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
0020
0021
0022 class AnyReference {
0023
0024 struct ReferenceHolderBase {
0025
0026
0027
0028
0029 virtual ~ReferenceHolderBase() {}
0030
0031
0032
0033
0034 virtual const std::type_info& type() const = 0;
0035
0036
0037
0038
0039 virtual ReferenceHolderBase* clone() const = 0;
0040
0041 };
0042
0043 template<class T>
0044 struct ReferenceHolder
0045 : public ReferenceHolderBase {
0046
0047
0048
0049
0050 T& value;
0051
0052
0053
0054
0055 static T& init() {
0056 static T v; return v;
0057 }
0058
0059
0060
0061
0062 ReferenceHolder()
0063 : value(init()) {}
0064
0065
0066
0067
0068 explicit ReferenceHolder(T& v)
0069 : value(v) {}
0070
0071
0072
0073
0074 virtual const std::type_info& type() const {
0075 return typeid(T);
0076 }
0077
0078
0079
0080
0081 virtual ReferenceHolderBase* clone() const {
0082 return new ReferenceHolder(*this);
0083 }
0084
0085 };
0086
0087
0088
0089
0090 ReferenceHolderBase* holder;
0091
0092 public:
0093
0094
0095
0096
0097 AnyReference()
0098 : holder(0) {}
0099
0100
0101
0102
0103 template<class T>
0104 AnyReference(T& v)
0105 : holder(new ReferenceHolder<T>(v)) {}
0106
0107
0108
0109
0110 AnyReference(const AnyReference& other)
0111 : holder(other.holder ? other.holder->clone() : 0) {}
0112
0113
0114
0115
0116 ~AnyReference() {
0117 delete holder; holder = 0;
0118 }
0119
0120 public:
0121
0122
0123
0124
0125 const std::type_info& type() const { return holder ? holder->type() : typeid(void); }
0126
0127
0128
0129
0130 bool empty() const { return !holder; }
0131
0132 public:
0133
0134
0135
0136
0137 AnyReference& swap(AnyReference& other) {
0138 std::swap(holder,other.holder); return *this;
0139 }
0140
0141
0142
0143
0144 template<class T>
0145 AnyReference& operator=(T& v) {
0146 AnyReference(v).swap(*this);
0147 return *this;
0148 }
0149
0150
0151
0152
0153 AnyReference& operator=(AnyReference other) {
0154 other.swap(*this);
0155 return *this;
0156 }
0157
0158
0159
0160
0161 void reset() {
0162 delete holder; holder = 0;
0163 }
0164
0165 public:
0166
0167
0168
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