NAMESPACE_UPP /* TRC 2/12/2003: obsoleted by Fidler's callback1 template struct Callback1MethodActionArg : public Callback1Action { OBJECT_ *object; METHOD_ method; T arg; void Execute(A a) { (object->*method)(a, arg); } bool IsEqual(const Callback1Action *other) const { const Callback1MethodActionArg *q = dynamic_cast *>(other); return q && q->object == object && q->method == method && q->arg == arg; } unsigned GetHashValue() const { return (unsigned)object ^ brutal_cast(method) ^ ::GetHashValue(arg); } Callback1MethodActionArg(OBJECT_ *object, METHOD_ method, T arg) : object(object), method(method), arg(arg) {} }; template Callback1 callback2(Object *object, R (O::*method)(A, B), T arg) { return Callback1(new Callback1MethodActionArg (object, method, arg)); } template Callback1 callback2(const Object *object, R (O::*method)(A, B) const, T arg) { return Callback1(new Callback1MethodActionArg (object, method, arg)); } */ /* template struct Callback1ActionCallArg : public Callback1Action { X x; T arg; void Execute(A a) { x(a, arg); } bool IsEqual(const Callback1Action *other) const { const Callback1ActionCallArg *q = dynamic_cast *>(other); return q && q->x == x && q->arg == arg; } unsigned GetHashValue() const { return ::GetHashValue(x) ^ ::GetHashValue(arg); } Callback1ActionCallArg(X x, T arg) : x(x), arg(arg) {} }; template Callback1 callback2(R (*fn)(A, B), T arg) { return Callback1(new Callback1ActionCallArg(fn, arg)); } */ //#define THISBACK2(m, a) callback2(this, &CLASSNAME::m, a) template void SerializeRaw(Stream& stream, T& object) { stream.SerializeRaw((byte *)&object, sizeof(object)); } template void SerializeEnum(Stream& stream, T& object) { int o = object; stream / o; object = T(o); } template static bool SerializeIn(T& object, String data) { StringStream stream(data); stream % object; return !stream.IsError(); } template static String SerializeOut(const T& object) { StringStream stream; stream % const_cast(object); return stream; } template class PtrValueRep : public RawValueRep { public: PtrValueRep(T *v) : RawValueRep(v) {} virtual bool IsNull() const { return this->v == 0; } virtual unsigned GetHashValue() const { return (unsigned)this->v; } virtual bool IsEqual(const Value::Void *p); virtual String AsString() { return FormatIntHex((int)this->v); } static const RawValueRep *Cast(const Value::Void *p) { ASSERT(dynamic_cast *>(p)); return (const RawValueRep *)p; } }; template bool PtrValueRep::IsEqual(const Value::Void *p) { const RawValueRep *cast = dynamic_cast *>(p); return cast && cast->Get() == this->v; } template class PtrValue : public Value { protected: typedef PtrValueRep Rep; public: PtrValue(T *x) : Value(new Rep(x)) {} T *Get(const Value& v) { return ::IsNull(v) ? 0 : Rep::Cast(v.GetVoidPtr())->Get(); } static T *Extract(const Value& v) { return ::IsNull(v) ? 0 : Rep::Cast(v.GetVoidPtr())->Get(); } }; template inline Value PtrToValue(T *p) { return PtrValue(p); } #ifdef COMPILER_GCC typedef std::type_info type_info; #endif template class TypeMap : Moveable< TypeMap > { public: One CreateObject(I id) const; I QueryObject(const T *object) const; One Copy(const One& object) const; void Serialize(Stream& stream, One& object) const; void Serialize(Stream& stream, Array& array) const; // template<> friend Stream& operator % (Stream& stream, One& object) { TypeMap::Serialize(stream, object); return stream; } One SerializeIn(const String& string) const; String SerializeOut(const One& object) const; typedef One (*NewFunc)(); void Register(NewFunc fn, const type_info *ti, I id); template struct NewType { static One New() { return new ST; } }; template void RegisterType(I id) { Register(&NewType::New, &typeid(ST), id); } public: Index id_index; Vector< One (*)()> factories; Index type_index; // static Index& GetIDIndex() { static Index index; return index; } // static Vector (*)()>& GetFactories() { static Vector (*)()> factories; return factories; } // static Index& GetTypeIndex() { static Index index; return index; } }; template One TypeMap::CreateObject(I id) const { if(IsNull(id)) return 0; int f = id_index.Find(id); if(f < 0) return 0; return factories[f](); } template I TypeMap::QueryObject(const T *object) const { if(!object) return Null; int i = type_index.Find(&typeid(*object)); return i >= 0 ? id_index[i] : I(Null); } template One TypeMap::Copy(const One& object) const { if(!object) return NULL; return this->SerializeIn(SerializeOut(object)); } template One TypeMap::SerializeIn(const String& string) const { One object; StringStream strm(string); Serialize(strm, object); return object; } template String TypeMap::SerializeOut(const One& object) const { StringStream ss; Serialize(ss, const_cast&>(object)); return ss; } template void TypeMap::Serialize(Stream& stream, One& object) const { I ID; if(stream.IsStoring()) ID = QueryObject(~object); stream / ID; if(stream.IsLoading()) { object = CreateObject(ID); if(object) stream % *object; else if(!IsNull(ID)) stream.SetError(); } else if(object) stream % *object; } template void TypeMap::Serialize(Stream& stream, Array& array) const { int c = array.GetCount(); stream % c; if(stream.IsStoring()) { for(int i = 0; i < c; i++) { I ID = QueryObject(&array[i]); stream / ID; stream % array[i]; } } else { array.SetCount(c); for(int i = 0; i < c; i++) { I ID; stream / ID; One object = CreateObject(ID); if(object) { array.Add(-object); stream % array.Top(); } else { stream.SetError(); return; } } } } template void TypeMap::Register(NewFunc fn, const type_info *ti, I id) { int tx = type_index.Find(ti); if(tx >= 0) ASSERT((id_index[tx] == id)); else { ASSERT((id_index.Find(id) < 0)); type_index.Add(ti); id_index.Add(id); factories.Add() = fn; } } template void StreamOne(Stream& stream, One& one) { bool full = one; stream % full; if(stream.IsLoading()) if(full) one = new T; else one = NULL; if(one) stream % *one; } template One StreamCopyOne(const One& one) { if(!one) return NULL; String aux = SerializeOut(*one); One out = new T; SerializeIn(*out, aux); return out; } template struct NewableType { typedef B *(*Factory)(); typedef VectorMap FactoryMap; static FactoryMap& Factories(); static B *New(const type_info& t); // throws on failure static B *NewNull(const type_info& t); // may return 0 static Factory GetFactory(const type_info& t); }; template typename NewableType::FactoryMap& NewableType::Factories() { static FactoryMap *pmap = 0; if(!pmap) // a nasty trick patching multiple construction compiler error { static FactoryMap map; pmap = ↦ } return *pmap; } template B *NewableType::New(const type_info& t) { B *ptr = NewNull(t); if(ptr == NULL) throw Exc(NFormat("Objekt '%s' není registrován.", t.name())); return ptr; } template B *NewableType::NewNull(const type_info& t) { Factory factory = GetFactory(t); return factory ? factory() : 0; } template typename NewableType::Factory NewableType::GetFactory(const type_info& t) { return Factories().Get(&t, 0); } template struct RegisterNewableType : NewableType { RegisterNewableType() { typename NewableType::Factory f = CreateObject; this->Factories().FindAdd(&typeid(C), f); } private: static B *CreateObject() { return new C; } }; ////////////////////////////////////////////////////////////////////// // RefMemStat: refcounted object memory statistics. #ifdef flagREFDEBUG #define REF_DEBUG #endif//flagREFDEBUG class RefMemStat { public: RefMemStat() {} RefMemStat(const RefMemStat& rms, int deep) : alloc_map(rms.alloc_map, 0) {} static RefMemStat& App(); void Add(const String& name, int allocindex); void Remove(const String& name, int allocindex); String Format(bool index = false) const; String FormatDelta(const RefMemStat& old, bool index = false) const; private: VectorMap > alloc_map; }; template class DeepCopyOption; ////////////////////////////////////////////////////////////////////// // RefBase: base for refcounted objects. /* TRC 2/12/2003: moved to Web/util template inline Value RefConToValue(RefCon p) { return StrongValue< RefCon >(p); } template inline Value RefPtrToValue(RefPtr p) { return StrongValue< RefPtr >(p); } */ class WeakBase : public Link { public: virtual ~WeakBase() { DbgChk(); } virtual void Clear() = 0; #ifdef _DEBUG void DbgChk() const { Chk(); } #else void DbgChk() const {} #endif void Chk() const; }; template class UPP::RefCon; template class UPP::RefPtr; class WeakRef; template class WeakCon : public WeakBase { friend class WeakRef; friend class UPP::RefCon; public: WeakCon() : ptr(0) {} WeakCon(const WeakCon& p) { p.Chk(); if(ptr = p.ptr) LinkAfter(ptr); Chk(); } WeakCon(const T *p) { if(ptr = const_cast(p)) LinkAfter(ptr); Chk(); } WeakCon(const RefCon& p) { if(ptr = const_cast(~p)) LinkAfter(ptr); Chk(); } ~WeakCon() { Chk(); } operator RefCon () const { return RefCon(ptr); } WeakCon& operator = (const T *p) { Chk(); Unlink(); if(ptr = const_cast(p)) LinkAfter(ptr); Chk(); return *this; } WeakCon& operator = (const WeakCon& p) { Chk(); Unlink(); if(ptr = p.ptr) LinkAfter(ptr); Chk(); return *this; } WeakCon& operator = (const RefCon& p) { Chk(); Unlink(); if(ptr = p.ptr) LinkAfter(ptr); Chk(); return *this; } virtual void Clear() { Chk(); Unlink(); ptr = 0; } bool IsEmpty() const { return ptr == NULL; } bool operator ! () const { return IsEmpty(); } const T *operator ~ () const { return ptr; } const T& operator * () const { ASSERT(ptr); return *ptr; } const T *operator -> () const { ASSERT(ptr); return ptr; } friend bool operator == (const WeakCon& a, const WeakCon& b) { return a.ptr == b.ptr; } friend bool operator != (const WeakCon& a, const WeakCon& b) { return a.ptr != b.ptr; } friend unsigned GetHashValue(const WeakCon& a) { return UPP::GetHashValue(a.ptr); } protected: T *ptr; }; template class WeakPtr : public WeakCon { public: WeakPtr() {} WeakPtr(const WeakPtr& p) : WeakCon(p) {} WeakPtr(T *p) : WeakCon(p) {} WeakPtr(const RefPtr& p) : WeakCon(p) {} operator RefPtr () const { return RefPtr(const_cast(this->ptr)); } WeakPtr& operator = (T *p) { this->Chk(); this->Unlink(); if(this->ptr = p) LinkAfter(this->ptr); this->Chk(); return *this; } WeakPtr& operator = (const WeakPtr& p) { this->Chk(); this->Unlink(); if(this->ptr = p.ptr) LinkAfter(this->ptr); this->Chk(); return *this; } WeakPtr& operator = (const RefPtr& p) { this->Chk(); this->Unlink(); if(this->ptr = ~p) LinkAfter(this->ptr); this->Chk(); return *this; } T *operator ~ () const { return const_cast(this->ptr); } T& operator * () const { ASSERT(this->ptr); return *const_cast(this->ptr); } T *operator -> () const { ASSERT(this->ptr); return const_cast(this->ptr); } }; class WeakRef : public Link { public: WeakRef() : refcount(0) {} virtual ~WeakRef() { ASSERT(refcount == 0); while(GetNext() != GetPtr()) GetNext()->Clear(); } int GetRefCount() const { return AtomicXAdd(refcount, 0); } void AddRef() const { if(this) AtomicInc(refcount); } void Release() const { if(this && !AtomicDec(refcount)) delete this; } private: mutable Atomic refcount; }; template class VirtualArrayData : public RefBase { public: virtual ~VirtualArrayData() {} virtual void SetCount(int count) = 0; virtual void SetCountR(int count) = 0; virtual int GetCount() const = 0; virtual void Set(int i, T t) = 0; virtual T Get(int i) const = 0; }; template class VirtualArray : Moveable< VirtualArray > { public: VirtualArray() {} VirtualArray(VirtualArrayData *data) : data(data) {} bool IsNullInstance() const { return !data; } void SetCount(int count) { data->SetCount(count); } void SetCountR(int count) { data->SetCountR(count); } int GetCount() const { return data->GetCount(); } void Set(int i, T t) { data->Set(i, t); } T Get(int i) const { return data->Get(i); } T operator [] (int i) const { ASSERT(i >= 0 && i < GetCount()); return Get(i); } void Add(T t) { int c = GetCount(); SetCountR(c + 1); Set(c, t); } void Clear() { data->SetCount(0); } bool IsEmpty() const { return data->GetCount() == 0; } typedef T ValueType; class ConstIterator { protected: const VirtualArray *cont; int ii; public: T operator*() const { return (*cont)[ii]; } T operator[](int i) const { return (*cont)[ii + i]; } ConstIterator& operator++() { ++ii; return *this; } ConstIterator& operator--() { --ii; return *this; } ConstIterator operator++(int) { ConstIterator t = *this; ++ii; return t; } ConstIterator operator--(int) { ConstIterator t = *this; --ii; return t; } ConstIterator& operator+=(int d) { ii += d; return *this; } ConstIterator& operator-=(int d) { ii -= d; return *this; } ConstIterator operator+(int d) const { return ConstIterator(cont, ii + d); } ConstIterator operator-(int d) const { return ConstIterator(cont, ii - d); } int operator-(const ConstIterator& b) const { return ii - b.ii; } bool operator==(const ConstIterator& b) const { return ii == b.ii; } bool operator!=(const ConstIterator& b) const { return ii != b.ii; } bool operator<(const ConstIterator& b) const { return ii < b.ii; } bool operator>(const ConstIterator& b) const { return ii > b.ii; } bool operator<=(const ConstIterator& b) const { return ii <= b.ii; } bool operator>=(const ConstIterator& b) const { return ii >= b.ii; } // operator bool() const { return ii < 0; } ConstIterator() { cont = NULL; ii = -1; } ConstIterator(const VirtualArray *_cont, int ii) : cont(_cont), ii(ii) {} }; ConstIterator Begin() const { return ConstIterator(this, 0); } ConstIterator End() const { return ConstIterator(this, GetCount()); } ConstIterator GetIter(int i) const { ASSERT(i >= 0 && i <= GetCount()); return ConstIterator(this, i); } private: RefPtr< VirtualArrayData > data; }; template class VirtualSegtorArray : public VirtualArrayData { public: virtual void SetCount(int count) { container.SetCount(count); } virtual void SetCountR(int count) { container.SetCount(count); } //!! Fidler: co takhle Segtor::SetCountR? virtual int GetCount() const { return container.GetCount(); } protected: Segtor container; }; template class VirtualStdSegtorArray : public VirtualSegtorArray { public: virtual void Set(int i, VT t) { this->container[i] = t; } virtual VT Get(int i) const { return this->container[i]; } }; template class VirtualValueArray : public VirtualStdSegtorArray { }; END_UPP_NAMESPACE