diff --git a/webrtc/api/statstypes.h b/webrtc/api/statstypes.h index 5d853708c9..e30760b47a 100644 --- a/webrtc/api/statstypes.h +++ b/webrtc/api/statstypes.h @@ -22,6 +22,7 @@ #include "webrtc/base/basictypes.h" #include "webrtc/base/common.h" #include "webrtc/base/constructormagic.h" +#include "webrtc/base/linked_ptr.h" #include "webrtc/base/refcount.h" #include "webrtc/base/scoped_ref_ptr.h" #include "webrtc/base/stringencode.h" @@ -320,7 +321,7 @@ class StatsReport { // TODO(tommi): Consider using a similar approach to how we store Ids using // scoped_refptr for values. - typedef std::unique_ptr ValuePtr; + typedef rtc::linked_ptr ValuePtr; typedef std::map Values; // Ownership of |id| is passed to |this|. diff --git a/webrtc/base/BUILD.gn b/webrtc/base/BUILD.gn index d5d03ed75b..5f68157e76 100644 --- a/webrtc/base/BUILD.gn +++ b/webrtc/base/BUILD.gn @@ -427,6 +427,7 @@ rtc_static_library("rtc_base") { "httpcommon.h", "ipaddress.cc", "ipaddress.h", + "linked_ptr.h", "messagedigest.cc", "messagedigest.h", "messagehandler.cc", diff --git a/webrtc/base/cryptstring.h b/webrtc/base/cryptstring.h index e1ee309f65..adaac2f36b 100644 --- a/webrtc/base/cryptstring.h +++ b/webrtc/base/cryptstring.h @@ -17,6 +17,8 @@ #include #include +#include "webrtc/base/linked_ptr.h" + namespace rtc { class CryptStringImpl { diff --git a/webrtc/base/linked_ptr.h b/webrtc/base/linked_ptr.h new file mode 100644 index 0000000000..65e5a00ecf --- /dev/null +++ b/webrtc/base/linked_ptr.h @@ -0,0 +1,125 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +/* + * linked_ptr - simple reference linked pointer + * (like reference counting, just using a linked list of the references + * instead of their count.) + * + * The implementation stores three pointers for every linked_ptr, but + * does not allocate anything on the free store. + */ + +#ifndef WEBRTC_BASE_LINKED_PTR_H__ +#define WEBRTC_BASE_LINKED_PTR_H__ + +namespace rtc { + +/* For ANSI-challenged compilers, you may want to #define + * NO_MEMBER_TEMPLATES, explicit or mutable */ +#define NO_MEMBER_TEMPLATES + +template class linked_ptr +{ +public: + +#ifndef NO_MEMBER_TEMPLATES +# define TEMPLATE_FUNCTION template + TEMPLATE_FUNCTION friend class linked_ptr; +#else +# define TEMPLATE_FUNCTION + typedef X Y; +#endif + + typedef X element_type; + + explicit linked_ptr(X* p = 0) throw() + : itsPtr(p) {itsPrev = itsNext = this;} + ~linked_ptr() + {release();} + linked_ptr(const linked_ptr& r) throw() + {acquire(r);} + linked_ptr& operator=(const linked_ptr& r) + { + if (this != &r) { + release(); + acquire(r); + } + return *this; + } + +#ifndef NO_MEMBER_TEMPLATES + template friend class linked_ptr; + template linked_ptr(const linked_ptr& r) throw() + {acquire(r);} + template linked_ptr& operator=(const linked_ptr& r) + { + if (this != &r) { + release(); + acquire(r); + } + return *this; + } +#endif // NO_MEMBER_TEMPLATES + + X& operator*() const throw() {return *itsPtr;} + X* operator->() const throw() {return itsPtr;} + X* get() const throw() {return itsPtr;} + bool unique() const throw() {return itsPrev ? itsPrev==this : true;} + +private: + X* itsPtr; + mutable const linked_ptr* itsPrev; + mutable const linked_ptr* itsNext; + + void acquire(const linked_ptr& r) throw() + { // insert this to the list + itsPtr = r.itsPtr; + itsNext = r.itsNext; + itsNext->itsPrev = this; + itsPrev = &r; +#ifndef mutable + r.itsNext = this; +#else // for ANSI-challenged compilers + (const_cast*>(&r))->itsNext = this; +#endif + } + +#ifndef NO_MEMBER_TEMPLATES + template void acquire(const linked_ptr& r) throw() + { // insert this to the list + itsPtr = r.itsPtr; + itsNext = r.itsNext; + itsNext->itsPrev = this; + itsPrev = &r; +#ifndef mutable + r.itsNext = this; +#else // for ANSI-challenged compilers + (const_cast*>(&r))->itsNext = this; +#endif + } +#endif // NO_MEMBER_TEMPLATES + + void release() + { // erase this from the list, delete if unique + if (unique()) delete itsPtr; + else { + itsPrev->itsNext = itsNext; + itsNext->itsPrev = itsPrev; + itsPrev = itsNext = 0; + } + itsPtr = 0; + } +}; + +} // namespace rtc + +#endif // WEBRTC_BASE_LINKED_PTR_H__ +