From bee9718e4f97a8acde0fdf70c0a6b47d1ca211b7 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Lars=20Gullik=20Bj=C3=B8nnes?= Date: Sat, 18 Aug 2001 11:41:10 +0000 Subject: [PATCH] new files git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@2545 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/support/ChangeLog | 6 + src/support/smart_ptr.h | 263 ++++++++++++++++++++++++++++++++++++++++ src/support/utility.h | 50 ++++++++ 3 files changed, 319 insertions(+) create mode 100644 src/support/smart_ptr.h create mode 100644 src/support/utility.h diff --git a/src/support/ChangeLog b/src/support/ChangeLog index db1f0053d7..351bd43e0a 100644 --- a/src/support/ChangeLog +++ b/src/support/ChangeLog @@ -1,3 +1,9 @@ +2001-08-18 Lars Gullik Bjønnes + + * smart_ptr.h: new file + + * utility.h: new file + 2001-08-01 John Levon * filetools.h: diff --git a/src/support/smart_ptr.h b/src/support/smart_ptr.h new file mode 100644 index 0000000000..9891749314 --- /dev/null +++ b/src/support/smart_ptr.h @@ -0,0 +1,263 @@ +// Baruch Even baruch@ev-en.org 2001-02-20 +// This version is a modified version for use in LyX +// The modifications are done in order to use it where exceptions are disabled +// Currently it has no "no memory" checks in place, asserts are probably the +// only real way. +// all changed are #ifded'ed by LYX_NO_EXCEPTIONS +#define LYX_NO_EXCEPTIONS + +// Boost smart_ptr.hpp header file -----------------------------------------// + +// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999. Permission to copy, +// use, modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided "as is" +// without express or implied warranty, and with no claim as to its +// suitability for any purpose. + +// See http://www.boost.org for most recent version including documentation. + +// Revision History +// 21 May 01 Require complete type where incomplete type is unsafe. +// (suggested by Vladimir Prus) +// 21 May 01 operator= fails if operand transitively owned by *this, as in a +// linked list (report by Ken Johnson, fix by Beman Dawes) +// 21 Jan 01 Suppress some useless warnings with MSVC (David Abrahams) +// 19 Oct 00 Make shared_ptr ctor from auto_ptr explicit. (Robert Vugts) +// 24 Jul 00 Change throw() to // never throws. See lib guidelines +// Exception-specification rationale. (Beman Dawes) +// 22 Jun 00 Remove #if continuations to fix GCC 2.95.2 problem (Beman Dawes) +// 1 Feb 00 Additional shared_ptr BOOST_NO_MEMBER_TEMPLATES workarounds +// (Dave Abrahams) +// 31 Dec 99 Condition tightened for no member template friend workaround +// (Dave Abrahams) +// 30 Dec 99 Moved BOOST_NMEMBER_TEMPLATES compatibility code to config.hpp +// (Dave Abrahams) +// 30 Nov 99 added operator ==, operator !=, and std::swap and std::less +// specializations for shared types (Darin Adler) +// 11 Oct 99 replaced op[](int) with op[](std::size_t) (Ed Brey, Valentin +// Bonnard), added shared_ptr workaround for no member template +// friends (Matthew Langston) +// 25 Sep 99 added shared_ptr::swap and shared_array::swap (Luis Coelho). +// 20 Jul 99 changed name to smart_ptr.hpp, #include , +// #include and use boost::noncopyable +// 17 May 99 remove scoped_array and shared_array operator*() as +// unnecessary (Beman Dawes) +// 14 May 99 reorder code so no effects when bad_alloc thrown (Abrahams/Dawes) +// 13 May 99 remove certain throw() specifiers to avoid generated try/catch +// code cost (Beman Dawes) +// 11 May 99 get() added, conversion to T* placed in macro guard (Valentin +// Bonnard, Dave Abrahams, and others argued for elimination +// of the automatic conversion) +// 28 Apr 99 #include fix (Valentin Bonnard) +// 28 Apr 99 rename transfer() to share() for clarity (Dave Abrahams) +// 28 Apr 99 remove unsafe shared_array template conversions(Valentin Bonnard) +// 28 Apr 99 p(r) changed to p(r.px) for clarity (Dave Abrahams) +// 21 Apr 99 reset() self assignment fix (Valentin Bonnard) +// 21 Apr 99 dispose() provided to improve clarity (Valentin Bonnard) +// 27 Apr 99 leak when new throws fixes (Dave Abrahams) +// 21 Oct 98 initial Version (Greg Colvin/Beman Dawes) + +#ifndef LYX_SMART_PTR_H +#define LYX_SMART_PTR_H + +#include // for broken compiler workarounds +#include // for std::size_t +#include // for std::auto_ptr +#include // for std::swap +#include "support/utility.h" // for boost::noncopyable, checked_delete, checked_array_delete +#include // for std::less +#include // for BOOST_STATIC_ASSERT + +#ifdef LYX_NO_EXCEPTIONS +#include +#endif + +namespace lyx { + +// shared_ptr --------------------------------------------------------------// + +// An enhanced relative of scoped_ptr with reference counted copy semantics. +// The object pointed to is deleted when the last shared_ptr pointing to it +// is destroyed or reset. + +template class shared_c_ptr { + public: + typedef T element_type; + + explicit shared_c_ptr(T* p =0) : px(p) { +#ifndef LYX_NO_EXCEPTIONS + try { pn = new long(1); } // fix: prevent leak if new throws + catch (...) { checked_delete(p); throw; } +#else + pn = new long(1); + assert(pn != 0); +#endif + } + + shared_c_ptr(const shared_c_ptr& r) : px(r.px) { ++*(pn = r.pn); } // never throws + + ~shared_c_ptr() { dispose(); } + + shared_c_ptr& operator=(const shared_c_ptr& r) { + share(r.px,r.pn); + return *this; + } + +#if !defined( BOOST_NO_MEMBER_TEMPLATES ) + template + shared_c_ptr(const shared_c_ptr& r) : px(r.px) { // never throws + ++*(pn = r.pn); + } +#ifndef BOOST_NO_AUTO_PTR + template + explicit shared_c_ptr(std::auto_ptr& r) { + pn = new long(1); // may throw + px = r.release(); // fix: moved here to stop leak if new throws + } +#endif + + template + shared_c_ptr& operator=(const shared_c_ptr& r) { + share(r.px,r.pn); + return *this; + } + +#ifndef BOOST_NO_AUTO_PTR + template + shared_c_ptr& operator=(std::auto_ptr& r) { + // code choice driven by guarantee of "no effect if new throws" + if (*pn == 1) { checked_delete(px); } + else { // allocate new reference counter + long * tmp = new long(1); // may throw + --*pn; // only decrement once danger of new throwing is past + pn = tmp; + } // allocate new reference counter + px = r.release(); // fix: moved here so doesn't leak if new throws + return *this; + } +#endif +#else +#ifndef BOOST_NO_AUTO_PTR + explicit shared_c_ptr(std::auto_ptr& r) { + pn = new long(1); // may throw + px = r.release(); // fix: moved here to stop leak if new throws + } + + shared_c_ptr& operator=(std::auto_ptr& r) { + // code choice driven by guarantee of "no effect if new throws" + if (*pn == 1) { checked_delete(px); } + else { // allocate new reference counter + long * tmp = new long(1); // may throw + --*pn; // only decrement once danger of new throwing is past + pn = tmp; + } // allocate new reference counter + px = r.release(); // fix: moved here so doesn't leak if new throws + return *this; + } +#endif +#endif + + void reset(T* p=0) { + if ( px == p ) return; // fix: self-assignment safe + if (--*pn == 0) { checked_delete(px); } + else { // allocate new reference counter +#ifndef LYX_NO_EXCEPTIONS + try { pn = new long; } // fix: prevent leak if new throws + catch (...) { + ++*pn; // undo effect of --*pn above to meet effects guarantee + checked_delete(p); + throw; + } // catch +#else + pn = new long; + assert(pn != 0); +#endif + } // allocate new reference counter + *pn = 1; + px = p; + } // reset + + T& operator*() const { return *px; } // never throws + T* operator->() const { return px; } // never throws + T* get() const { return px; } // never throws + + long use_count() const { return *pn; } // never throws + bool unique() const { return *pn == 1; } // never throws + + void swap(shared_c_ptr& other) // never throws + { std::swap(px,other.px); std::swap(pn,other.pn); } + +// Tasteless as this may seem, making all members public allows member templates +// to work in the absence of member template friends. (Matthew Langston) +// Don't split this line into two; that causes problems for some GCC 2.95.2 builds +#if defined(BOOST_NO_MEMBER_TEMPLATES) || !defined( BOOST_NO_MEMBER_TEMPLATE_FRIENDS ) + private: +#endif + + T* px; // contained pointer + long* pn; // ptr to reference counter + +// Don't split this line into two; that causes problems for some GCC 2.95.2 builds +#if !defined( BOOST_NO_MEMBER_TEMPLATES ) && !defined( BOOST_NO_MEMBER_TEMPLATE_FRIENDS ) + template friend class shared_ptr; +#endif + + void dispose() { if (--*pn == 0) { checked_delete(px); delete pn; } } + + void share(T* rpx, long* rpn) { + if (pn != rpn) { // Q: why not px != rpx? A: fails when both == 0 + ++*rpn; // done before dispose() in case rpn transitively + // dependent on *this (bug reported by Ken Johnson) + dispose(); + px = rpx; + pn = rpn; + } + } // share +}; // shared_ptr + +template + inline bool operator==(const shared_c_ptr& a, const shared_c_ptr& b) + { return a.get() == b.get(); } + +template + inline bool operator!=(const shared_c_ptr& a, const shared_c_ptr& b) + { return a.get() != b.get(); } + +} // namespace boost + +// specializations for things in namespace std -----------------------------// + +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + +namespace std { + +// Specialize std::swap to use the fast, non-throwing swap that's provided +// as a member function instead of using the default algorithm which creates +// a temporary and uses assignment. + +template + inline void swap(lyx::shared_c_ptr& a, lyx::shared_c_ptr& b) + { a.swap(b); } + +// Specialize std::less so we can use shared pointers and arrays as keys in +// associative collections. + +// It's still a controversial question whether this is better than supplying +// a full range of comparison operators (<, >, <=, >=). + +template + struct less< lyx::shared_c_ptr > + : binary_function, lyx::shared_c_ptr, bool> + { + bool operator()(const lyx::shared_c_ptr& a, + const lyx::shared_c_ptr& b) const + { return less()(a.get(),b.get()); } + }; + +} // namespace std + +#endif // ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + +#endif // LYX_SMART_PTR_H + + diff --git a/src/support/utility.h b/src/support/utility.h new file mode 100644 index 0000000000..e00ca0cb51 --- /dev/null +++ b/src/support/utility.h @@ -0,0 +1,50 @@ +// boost utility.hpp header file -------------------------------------------// + +// (C) Copyright boost.org 1999. Permission to copy, use, modify, sell +// and distribute this software is granted provided this copyright +// notice appears in all copies. This software is provided "as is" without +// express or implied warranty, and with no claim as to its suitability for +// any purpose. + +// See http://www.boost.org for most recent version including documentation. + +// Classes appear in alphabetical order + +// Revision History +// 21 May 01 checked_delete() and checked_array_delete() added (Beman Dawes, +// suggested by Dave Abrahams, generalizing idea from Vladimir Prus) +// 21 May 01 made next() and prior() inline (Beman Dawes) +// 26 Jan 00 protected noncopyable destructor added (Miki Jovanovic) +// 10 Dec 99 next() and prior() templates added (Dave Abrahams) +// 30 Aug 99 moved cast templates to cast.hpp (Beman Dawes) +// 3 Aug 99 cast templates added +// 20 Jul 99 name changed to utility.hpp +// 9 Jun 99 protected noncopyable default ctor +// 2 Jun 99 Initial Version. Class noncopyable only contents (Dave Abrahams) + +#ifndef LYX_UTILITY_H +#define LYX_UTILITY_H + +#include // broken compiler workarounds +#include +//#include // for size_t +//#include // for std::pair + +namespace lyx +{ +// checked_delete() and checked_array_delete() -----------------------------// + + // verify that types are complete for increased safety + + template< typename T > + inline void checked_delete(T * x) + { + BOOST_STATIC_ASSERT( sizeof(T) != 0 ); // assert type complete at point + // of instantiation + free(x); + } + +} // namespace boost + +#endif // BOOST_UTILITY_HPP + -- 2.39.5