From patchwork Wed Nov 9 01:25:27 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pedro Alves X-Patchwork-Id: 17332 Received: (qmail 106808 invoked by alias); 9 Nov 2016 01:25:41 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 106774 invoked by uid 89); 9 Nov 2016 01:25:40 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-4.8 required=5.0 tests=BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=equally, 1760, emulate, shares X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 09 Nov 2016 01:25:30 +0000 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E5BC681236 for ; Wed, 9 Nov 2016 01:25:28 +0000 (UTC) Received: from cascais.lan (ovpn01.gateway.prod.ext.ams2.redhat.com [10.39.146.11]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id uA91PRMB030734 for ; Tue, 8 Nov 2016 20:25:28 -0500 From: Pedro Alves To: gdb-patches@sourceware.org Subject: [PATCH] Delete gdb::unique_ptr/gdb::move Date: Wed, 9 Nov 2016 01:25:27 +0000 Message-Id: <1478654727-32352-1-git-send-email-palves@redhat.com> Now that we require C++11 and the previous patches I sent (once applied) removed all uses of gdb::unique_ptr and gdb::move, let's remove their definitions... With my lazy hat on, I repurposed the header for "generally useful unique_ptr specializations", and left gdb::unique_xmalloc_ptr in there. Not sure whether we should move it out of the gdb namespace or leave it be. I left it because it's less work and avoids disrupting yet-unmerged patches that use it. gdb/ChangeLog: yyyy-mm-dd Pedro Alves * common/common-defs.h: Update comment. * common/gdb_unique_ptr.h: Update header comment and copyright year. (gdb::unique_ptr, gdb::move): Delete. --- gdb/common/common-defs.h | 2 +- gdb/common/gdb_unique_ptr.h | 353 +------------------------------------------- 2 files changed, 7 insertions(+), 348 deletions(-) diff --git a/gdb/common/common-defs.h b/gdb/common/common-defs.h index 8fbb4bf..69254c8 100644 --- a/gdb/common/common-defs.h +++ b/gdb/common/common-defs.h @@ -87,7 +87,7 @@ #define EXTERN_C_PUSH extern "C" { #define EXTERN_C_POP } -/* Pull in gdb::unique_ptr and gdb::unique_xmalloc_ptr. */ +/* Pull in gdb::unique_xmalloc_ptr. */ #include "common/gdb_unique_ptr.h" #endif /* COMMON_DEFS_H */ diff --git a/gdb/common/gdb_unique_ptr.h b/gdb/common/gdb_unique_ptr.h index e881e38..86a0d2f 100644 --- a/gdb/common/gdb_unique_ptr.h +++ b/gdb/common/gdb_unique_ptr.h @@ -1,6 +1,6 @@ -/* gdb::unique_ptr, a simple std::unique_ptr replacement for C++03. +/* std::unique_ptr specializations for GDB. - Copyright (C) 2007-2016 Free Software Foundation, Inc. + Copyright (C) 2016 Free Software Foundation, Inc. This file is part of GDB. @@ -17,60 +17,6 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -/* gdb::unique_ptr defines a C++ owning smart pointer that exposes a - subset of the std::unique_ptr API. - - In fact, when compiled with a C++11 compiler, gdb::unique_ptr - actually _is_ std::unique_ptr. When compiled with a C++03 compiler - OTOH, it's an hand coded std::unique_ptr emulation that assumes - code is correct and doesn't try to be too smart. - - This supports custom deleters, but not _stateful_ deleters, so you - can't use those in C++11 mode either. Only the managed pointer is - stored in the smart pointer. That could be changed; it simply - wasn't found necessary. - - At the end of the file you'll find a gdb::unique_ptr partial - specialization that uses a custom (stateless) deleter: - gdb::unique_xmalloc_ptr. That is used to manage pointers to - objects allocated with xmalloc. - - The C++03 version was originally based on GCC 7.0's std::auto_ptr - and then heavily customized to behave more like C++11's - std::unique_ptr, but at this point, it no longer shares much at all - with the original file. But, that's the history and the reason for - the copyright's starting year. - - The C++03 version lets you shoot yourself in the foot, since - similarly to std::auto_ptr, the copy constructor and assignment - operators actually move. Also, in the name of simplicity, no - effort is spent on using SFINAE to prevent invalid conversions, - etc. This is not really a problem, because the goal here is to - allow code that would be correct using std::unique_ptr to be - equally correct in C++03 mode, and, just as efficient. If client - code compiles correctly with a C++11 (or newer) compiler, we know - we're not doing anything invalid by mistake. - - Usage notes: - - - Putting gdb::unique_ptr in standard containers is not supported, - since C++03 containers are not move-aware (and our emulation - relies on copy actually moving). - - - Since there's no nullptr in C++03, gdb::unique_ptr allows - implicit initialization and assignment from NULL instead. - - - To check whether there's an associated managed object, all these - work as expected: - - if (ptr) - if (!ptr) - if (ptr != NULL) - if (ptr == NULL) - if (NULL != ptr) - if (NULL == ptr) -*/ - #ifndef GDB_UNIQUE_PTR_H #define GDB_UNIQUE_PTR_H 1 @@ -78,309 +24,22 @@ namespace gdb { - -#if __cplusplus >= 201103 - -/* In C++11 mode, all we need is import the standard - std::unique_ptr. */ -template using unique_ptr = std::unique_ptr; - -/* Pull in move as well. */ -using std::move; - -#else /* C++11 */ - -/* Default destruction policy used by gdb::unique_ptr when no deleter - is specified. Uses delete. */ - -template -struct default_delete -{ - void operator () (T *ptr) const { delete ptr; } -}; - -/* Specialization for arrays. Uses delete[]. */ - -template -struct default_delete -{ - void operator () (T *ptr) const { delete [] ptr; } -}; - -namespace detail -{ -/* Type used to support implicit construction from NULL: - - gdb::unique_ptr func (....) - { - return NULL; - } - - and assignment from NULL: - - gdb::unique_ptr ptr (....); - ... - ptr = NULL; - - It is intentionally not defined anywhere. */ -struct nullptr_t; - -/* Base class of our unique_ptr emulation. Contains code common to - both unique_ptr and unique_ptr. */ - -template -class unique_ptr_base -{ -public: - typedef T *pointer; - typedef T element_type; - typedef D deleter_type; - - /* Takes ownership of a pointer. P is a pointer to an object of - element_type type. Defaults to NULL. */ - explicit unique_ptr_base (element_type *p = NULL) throw () : m_ptr (p) {} - - /* The "move" constructor. Really a copy constructor that actually - moves. Even though std::unique_ptr is not copyable, our little - simpler emulation allows it, because: - - - There are no rvalue references in C++03. Our move emulation - instead relies on copy/assignment moving, like std::auto_ptr. - - RVO/NRVO requires an accessible copy constructor - */ - unique_ptr_base (const unique_ptr_base &other) throw () - : m_ptr (const_cast (other).release ()) {} - - /* Converting "move" constructor. Really an lvalue ref converting - constructor that actually moves. This allows constructs such as: - - unique_ptr func_returning_unique_ptr (.....); - ... - unique_ptr ptr = func_returning_unique_ptr (.....); - */ - template - unique_ptr_base (const unique_ptr_base &other) throw () - : m_ptr (const_cast &> (other).release ()) {} - - /* The "move" assignment operator. Really an lvalue ref copy - assignment operator that actually moves. See comments above. */ - unique_ptr_base &operator= (const unique_ptr_base &other) throw () - { - reset (const_cast (other).release ()); - return *this; - } - - /* Converting "move" assignment. Really an lvalue ref converting - copy assignment operator that moves. See comments above. */ - template - unique_ptr_base &operator= (const unique_ptr_base &other) throw () - { - reset (const_cast &> (other).release ()); - return *this; - } - - /* std::unique_ptr does not allow assignment, except from nullptr. - nullptr doesn't exist in C++03, so we allow assignment from NULL - instead [ptr = NULL;]. - */ - unique_ptr_base &operator= (detail::nullptr_t *) throw () - { - reset (); - return *this; - } - - ~unique_ptr_base () { call_deleter (); } - - /* "explicit operator bool ()" emulation using the safe bool - idiom. */ -private: - typedef void (unique_ptr_base::*explicit_operator_bool) () const; - void this_type_does_not_support_comparisons () const {} - -public: - operator explicit_operator_bool () const - { - return (m_ptr != NULL - ? &unique_ptr_base::this_type_does_not_support_comparisons - : 0); - } - - element_type *get () const throw () { return m_ptr; } - - element_type *release () throw () - { - pointer tmp = m_ptr; - m_ptr = NULL; - return tmp; - } - - void reset (element_type *p = NULL) throw () - { - if (p != m_ptr) - { - call_deleter (); - m_ptr = p; - } - } - -private: - - /* Call the deleter. Note we assume the deleter is "stateless". */ - void call_deleter () - { - D d; - - d (m_ptr); - } - - element_type *m_ptr; -}; - -} /* namespace detail */ - -/* Macro used to create a unique_ptr_base "partial specialization" -- - a subclass that uses a specific deleter. Basically this re-defines - the necessary constructors. This is necessary because C++03 - doesn't support inheriting constructors with "using". While at it, - we inherit the assignment operator. TYPE is the name of the type - being defined. Assumes that 'base_type' is a typedef of the - baseclass TYPE is inheriting from. */ -#define DEFINE_GDB_UNIQUE_PTR(TYPE) \ -public: \ - explicit TYPE (T *p = NULL) throw () \ - : base_type (p) {} \ - \ - TYPE (const TYPE &other) throw () : base_type (other) {} \ - \ - TYPE (detail::nullptr_t *) throw () : base_type (NULL) {} \ - \ - template \ - TYPE (const detail::unique_ptr_base &other) throw () \ - : base_type (other) {} \ - \ - using base_type::operator=; - -/* Define single-object gdb::unique_ptr. */ - -template > -class unique_ptr : public detail::unique_ptr_base -{ - typedef detail::unique_ptr_base base_type; - - DEFINE_GDB_UNIQUE_PTR (unique_ptr) - -public: - /* Dereferencing. */ - T &operator* () const throw () { return *this->get (); } - T *operator-> () const throw () { return this->get (); } -}; - -/* Define gdb::unique_ptr specialization for T[]. */ - -template -class unique_ptr : public detail::unique_ptr_base -{ - typedef detail::unique_ptr_base base_type; - - DEFINE_GDB_UNIQUE_PTR (unique_ptr) - -public: - /* Indexing operator. */ - T &operator[] (size_t i) const { return this->get ()[i]; } -}; - -/* Comparison operators. */ - -template -inline bool -operator== (const detail::unique_ptr_base &x, - const detail::unique_ptr_base &y) -{ return x.get() == y.get(); } - -template -inline bool -operator!= (const detail::unique_ptr_base &x, - const detail::unique_ptr_base &y) -{ return x.get() != y.get(); } - -template -inline bool -operator< (const detail::unique_ptr_base &x, - const detail::unique_ptr_base &y) -{ return x.get() < y.get (); } - -template -inline bool -operator<= (const detail::unique_ptr_base &x, - const detail::unique_ptr_base &y) -{ return !(y < x); } - -template -inline bool -operator> (const detail::unique_ptr_base &x, - const detail::unique_ptr_base &y) -{ return y < x; } - -template -inline bool -operator>= (const detail::unique_ptr_base &x, - const detail::unique_ptr_base &y) -{ return !(x < y); } - -/* std::move "emulation". This is as simple as it can be -- no - attempt is made to emulate rvalue references. Instead relies on - the fact that gdb::unique_ptr has move semantics like - std::auto_ptr. I.e., copy/assignment actually moves. */ - -template -unique_ptr -move (unique_ptr v) -{ - return v; -} - -#endif /* C++11 */ - -/* Define gdb::unique_xmalloc_ptr, a gdb::unique_ptr that manages +/* Define gdb::unique_xmalloc_ptr, a std::unique_ptr that manages xmalloc'ed memory. */ -/* The deleter for gdb::unique_xmalloc_ptr. Uses xfree. */ +/* The deleter for std::unique_xmalloc_ptr. Uses xfree. */ template struct xfree_deleter { void operator() (T *ptr) const { xfree (ptr); } }; -#if __cplusplus >= 201103 - -/* In C++11, we just import the standard unique_ptr to our namespace - with a custom deleter. */ +/* Import the standard unique_ptr to our namespace with a custom + deleter. */ template using unique_xmalloc_ptr = std::unique_ptr>; -#else /* C++11 */ - -/* In C++03, we don't have template aliases, so we need to define a - subclass instead, and re-define the constructors, because C++03 - doesn't support inheriting constructors either. */ - -template -class unique_xmalloc_ptr : public unique_ptr > -{ - typedef unique_ptr > base_type; - - DEFINE_GDB_UNIQUE_PTR (unique_xmalloc_ptr) -}; - -#endif /* C++11 */ - } /* namespace gdb */ #endif /* GDB_UNIQUE_PTR_H */