2016-11-16 03:54:21 +08:00
|
|
|
/* std::unique_ptr specializations for GDB.
|
Introduce gdb::unique_ptr
Many make_cleanup uses in the code base are best eliminated by using a
"owning" smart pointer to manage ownership of the resource
automatically.
The question is _which_ smart pointer.
GDB currently supports building with a C++03 compiler. We have
std::auto_ptr in C++03, but, as is collective wisdom by now, that's
too easy to misuse, and has therefore been deprecated in C++11 and
finally removed in C++17.
It'd be nice to be able to use std::unique_ptr instead, which is the
modern, safe std::auto_ptr replacement in C++11.
In addition to extra safety -- moving (i.e., transfer of ownership of
the managed pointer between smart pointers) must be explicit --
std::unique_ptr has (among others) one nice feature that std::auto_ptr
doesn't --- ability to specify a custom deleter as template parameter.
In gdb's context, that allows easily creating a smart pointer for
memory allocated with xmalloc -- the smart pointer then knows to
release with xfree instead of delete. This is particularly
interesting when managing objects allocated in C libraries, and also,
for C++-fying parts of GDB that interact with other parts that still
return objects allocated with xmalloc.
Since std::unique_ptr's API is quite nice, and eventually we'd like to
move to C++11, this patch adds a C++03-compatible smart pointer that
exposes the subset of the std::unique_ptr API that we're interested
in. An advantage is that whenever we start requiring C++11, we won't
have to learn a new API. Meanwhile, this allows continuing to support
building with a C++03 compiler.
Since C++03 doesn't support rvalue references (boost gets close to
emulating them, but it's not fully transparent to user code), the
C++03 std::unique_ptr emulation here doesn't try hard to prevent
accidentally moving, which is where most of complication of a more
thorough emulation would be. Instead, we rely on the fact that GDB
will be usually compiled with a C++11 compiler, and use the real
std::unique_ptr in that case to catch such accidental moves. IOW, 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.
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:
- Support for custom (stateless) deleters. (Support for stateful
deleters could be added, if necessary.)
- unique_ptr<T[]> partial specialization (auto_ptr<T> does not know
to use delete[]).
- Support for all of 'ptr != NULL', 'ptr == NULL' and 'if (ptr)'
using the safe bool idiom to emulate C++11's explicit bool
operator.
- There's no nullptr in C++03, so this allows initialization and
assignment from NULL instead (std::auto_ptr allows neither).
- Variable names un-uglified (ie., no leading __ prefix everywhere).
- Formatting made to follow GDB's coding conventions, including
comment style.
- Converting "move" constructors done differently in order to truly
support:
unique_ptr<Derived> func_returning_unique_ptr (.....);
...
unique_ptr<Base> ptr = func_returning_unique_ptr (.....);
At this point, it no longer shares much at all with the original file,
but, that's the history.
See comments in the code to find out more.
I thought of putting the "emulation" / shim in the "std" namespace, so
that when we start requiring C++11 at some point, no actual changes to
users of the smart pointer throughout would be necessary. Putting
things in the std namespace is technically undefined, however in
practice it doesn't cause any issue with any compiler. However,
thinking that people might be confused with seeing std::unique_ptr and
thinking that we're actually requiring C++11 already, I put the new
types in the "gdb" namespace instead.
For managing xmalloc pointers, this adds a gdb::unique_xmalloc_ptr<T>
"specialization" with a custom xfree deleter.
No actual use of any smart pointer is introduced in this patch.
That'll be done in following patches.
Tested (along with the rest of the series) on:
- NetBSD 5.1 (gcc70 on the compile farm), w/ gcc 4.1.3
- x86-64 Fedora 23, gcc 5.3.1 (gnu++03)
- x86-64 Fedora 23, and gcc 7.0 (gnu++14)
gdb/ChangeLog:
2016-10-18 Pedro Alves <palves@redhat.com>
* common/common-defs.h: Include "gdb_unique_ptr.h".
* common/gdb_unique_ptr.h: New.
2016-10-18 18:42:35 +08:00
|
|
|
|
2024-01-12 23:30:44 +08:00
|
|
|
Copyright (C) 2016-2024 Free Software Foundation, Inc.
|
Introduce gdb::unique_ptr
Many make_cleanup uses in the code base are best eliminated by using a
"owning" smart pointer to manage ownership of the resource
automatically.
The question is _which_ smart pointer.
GDB currently supports building with a C++03 compiler. We have
std::auto_ptr in C++03, but, as is collective wisdom by now, that's
too easy to misuse, and has therefore been deprecated in C++11 and
finally removed in C++17.
It'd be nice to be able to use std::unique_ptr instead, which is the
modern, safe std::auto_ptr replacement in C++11.
In addition to extra safety -- moving (i.e., transfer of ownership of
the managed pointer between smart pointers) must be explicit --
std::unique_ptr has (among others) one nice feature that std::auto_ptr
doesn't --- ability to specify a custom deleter as template parameter.
In gdb's context, that allows easily creating a smart pointer for
memory allocated with xmalloc -- the smart pointer then knows to
release with xfree instead of delete. This is particularly
interesting when managing objects allocated in C libraries, and also,
for C++-fying parts of GDB that interact with other parts that still
return objects allocated with xmalloc.
Since std::unique_ptr's API is quite nice, and eventually we'd like to
move to C++11, this patch adds a C++03-compatible smart pointer that
exposes the subset of the std::unique_ptr API that we're interested
in. An advantage is that whenever we start requiring C++11, we won't
have to learn a new API. Meanwhile, this allows continuing to support
building with a C++03 compiler.
Since C++03 doesn't support rvalue references (boost gets close to
emulating them, but it's not fully transparent to user code), the
C++03 std::unique_ptr emulation here doesn't try hard to prevent
accidentally moving, which is where most of complication of a more
thorough emulation would be. Instead, we rely on the fact that GDB
will be usually compiled with a C++11 compiler, and use the real
std::unique_ptr in that case to catch such accidental moves. IOW, 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.
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:
- Support for custom (stateless) deleters. (Support for stateful
deleters could be added, if necessary.)
- unique_ptr<T[]> partial specialization (auto_ptr<T> does not know
to use delete[]).
- Support for all of 'ptr != NULL', 'ptr == NULL' and 'if (ptr)'
using the safe bool idiom to emulate C++11's explicit bool
operator.
- There's no nullptr in C++03, so this allows initialization and
assignment from NULL instead (std::auto_ptr allows neither).
- Variable names un-uglified (ie., no leading __ prefix everywhere).
- Formatting made to follow GDB's coding conventions, including
comment style.
- Converting "move" constructors done differently in order to truly
support:
unique_ptr<Derived> func_returning_unique_ptr (.....);
...
unique_ptr<Base> ptr = func_returning_unique_ptr (.....);
At this point, it no longer shares much at all with the original file,
but, that's the history.
See comments in the code to find out more.
I thought of putting the "emulation" / shim in the "std" namespace, so
that when we start requiring C++11 at some point, no actual changes to
users of the smart pointer throughout would be necessary. Putting
things in the std namespace is technically undefined, however in
practice it doesn't cause any issue with any compiler. However,
thinking that people might be confused with seeing std::unique_ptr and
thinking that we're actually requiring C++11 already, I put the new
types in the "gdb" namespace instead.
For managing xmalloc pointers, this adds a gdb::unique_xmalloc_ptr<T>
"specialization" with a custom xfree deleter.
No actual use of any smart pointer is introduced in this patch.
That'll be done in following patches.
Tested (along with the rest of the series) on:
- NetBSD 5.1 (gcc70 on the compile farm), w/ gcc 4.1.3
- x86-64 Fedora 23, gcc 5.3.1 (gnu++03)
- x86-64 Fedora 23, and gcc 7.0 (gnu++14)
gdb/ChangeLog:
2016-10-18 Pedro Alves <palves@redhat.com>
* common/common-defs.h: Include "gdb_unique_ptr.h".
* common/gdb_unique_ptr.h: New.
2016-10-18 18:42:35 +08:00
|
|
|
|
|
|
|
This file is part of GDB.
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation; either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
|
|
|
|
2019-01-28 03:51:36 +08:00
|
|
|
#ifndef COMMON_GDB_UNIQUE_PTR_H
|
|
|
|
#define COMMON_GDB_UNIQUE_PTR_H
|
Introduce gdb::unique_ptr
Many make_cleanup uses in the code base are best eliminated by using a
"owning" smart pointer to manage ownership of the resource
automatically.
The question is _which_ smart pointer.
GDB currently supports building with a C++03 compiler. We have
std::auto_ptr in C++03, but, as is collective wisdom by now, that's
too easy to misuse, and has therefore been deprecated in C++11 and
finally removed in C++17.
It'd be nice to be able to use std::unique_ptr instead, which is the
modern, safe std::auto_ptr replacement in C++11.
In addition to extra safety -- moving (i.e., transfer of ownership of
the managed pointer between smart pointers) must be explicit --
std::unique_ptr has (among others) one nice feature that std::auto_ptr
doesn't --- ability to specify a custom deleter as template parameter.
In gdb's context, that allows easily creating a smart pointer for
memory allocated with xmalloc -- the smart pointer then knows to
release with xfree instead of delete. This is particularly
interesting when managing objects allocated in C libraries, and also,
for C++-fying parts of GDB that interact with other parts that still
return objects allocated with xmalloc.
Since std::unique_ptr's API is quite nice, and eventually we'd like to
move to C++11, this patch adds a C++03-compatible smart pointer that
exposes the subset of the std::unique_ptr API that we're interested
in. An advantage is that whenever we start requiring C++11, we won't
have to learn a new API. Meanwhile, this allows continuing to support
building with a C++03 compiler.
Since C++03 doesn't support rvalue references (boost gets close to
emulating them, but it's not fully transparent to user code), the
C++03 std::unique_ptr emulation here doesn't try hard to prevent
accidentally moving, which is where most of complication of a more
thorough emulation would be. Instead, we rely on the fact that GDB
will be usually compiled with a C++11 compiler, and use the real
std::unique_ptr in that case to catch such accidental moves. IOW, 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.
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:
- Support for custom (stateless) deleters. (Support for stateful
deleters could be added, if necessary.)
- unique_ptr<T[]> partial specialization (auto_ptr<T> does not know
to use delete[]).
- Support for all of 'ptr != NULL', 'ptr == NULL' and 'if (ptr)'
using the safe bool idiom to emulate C++11's explicit bool
operator.
- There's no nullptr in C++03, so this allows initialization and
assignment from NULL instead (std::auto_ptr allows neither).
- Variable names un-uglified (ie., no leading __ prefix everywhere).
- Formatting made to follow GDB's coding conventions, including
comment style.
- Converting "move" constructors done differently in order to truly
support:
unique_ptr<Derived> func_returning_unique_ptr (.....);
...
unique_ptr<Base> ptr = func_returning_unique_ptr (.....);
At this point, it no longer shares much at all with the original file,
but, that's the history.
See comments in the code to find out more.
I thought of putting the "emulation" / shim in the "std" namespace, so
that when we start requiring C++11 at some point, no actual changes to
users of the smart pointer throughout would be necessary. Putting
things in the std namespace is technically undefined, however in
practice it doesn't cause any issue with any compiler. However,
thinking that people might be confused with seeing std::unique_ptr and
thinking that we're actually requiring C++11 already, I put the new
types in the "gdb" namespace instead.
For managing xmalloc pointers, this adds a gdb::unique_xmalloc_ptr<T>
"specialization" with a custom xfree deleter.
No actual use of any smart pointer is introduced in this patch.
That'll be done in following patches.
Tested (along with the rest of the series) on:
- NetBSD 5.1 (gcc70 on the compile farm), w/ gcc 4.1.3
- x86-64 Fedora 23, gcc 5.3.1 (gnu++03)
- x86-64 Fedora 23, and gcc 7.0 (gnu++14)
gdb/ChangeLog:
2016-10-18 Pedro Alves <palves@redhat.com>
* common/common-defs.h: Include "gdb_unique_ptr.h".
* common/gdb_unique_ptr.h: New.
2016-10-18 18:42:35 +08:00
|
|
|
|
|
|
|
#include <memory>
|
2022-02-21 22:07:45 +08:00
|
|
|
#include <string>
|
2021-11-08 23:17:16 +08:00
|
|
|
#include "gdbsupport/gdb-xfree.h"
|
Introduce gdb::unique_ptr
Many make_cleanup uses in the code base are best eliminated by using a
"owning" smart pointer to manage ownership of the resource
automatically.
The question is _which_ smart pointer.
GDB currently supports building with a C++03 compiler. We have
std::auto_ptr in C++03, but, as is collective wisdom by now, that's
too easy to misuse, and has therefore been deprecated in C++11 and
finally removed in C++17.
It'd be nice to be able to use std::unique_ptr instead, which is the
modern, safe std::auto_ptr replacement in C++11.
In addition to extra safety -- moving (i.e., transfer of ownership of
the managed pointer between smart pointers) must be explicit --
std::unique_ptr has (among others) one nice feature that std::auto_ptr
doesn't --- ability to specify a custom deleter as template parameter.
In gdb's context, that allows easily creating a smart pointer for
memory allocated with xmalloc -- the smart pointer then knows to
release with xfree instead of delete. This is particularly
interesting when managing objects allocated in C libraries, and also,
for C++-fying parts of GDB that interact with other parts that still
return objects allocated with xmalloc.
Since std::unique_ptr's API is quite nice, and eventually we'd like to
move to C++11, this patch adds a C++03-compatible smart pointer that
exposes the subset of the std::unique_ptr API that we're interested
in. An advantage is that whenever we start requiring C++11, we won't
have to learn a new API. Meanwhile, this allows continuing to support
building with a C++03 compiler.
Since C++03 doesn't support rvalue references (boost gets close to
emulating them, but it's not fully transparent to user code), the
C++03 std::unique_ptr emulation here doesn't try hard to prevent
accidentally moving, which is where most of complication of a more
thorough emulation would be. Instead, we rely on the fact that GDB
will be usually compiled with a C++11 compiler, and use the real
std::unique_ptr in that case to catch such accidental moves. IOW, 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.
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:
- Support for custom (stateless) deleters. (Support for stateful
deleters could be added, if necessary.)
- unique_ptr<T[]> partial specialization (auto_ptr<T> does not know
to use delete[]).
- Support for all of 'ptr != NULL', 'ptr == NULL' and 'if (ptr)'
using the safe bool idiom to emulate C++11's explicit bool
operator.
- There's no nullptr in C++03, so this allows initialization and
assignment from NULL instead (std::auto_ptr allows neither).
- Variable names un-uglified (ie., no leading __ prefix everywhere).
- Formatting made to follow GDB's coding conventions, including
comment style.
- Converting "move" constructors done differently in order to truly
support:
unique_ptr<Derived> func_returning_unique_ptr (.....);
...
unique_ptr<Base> ptr = func_returning_unique_ptr (.....);
At this point, it no longer shares much at all with the original file,
but, that's the history.
See comments in the code to find out more.
I thought of putting the "emulation" / shim in the "std" namespace, so
that when we start requiring C++11 at some point, no actual changes to
users of the smart pointer throughout would be necessary. Putting
things in the std namespace is technically undefined, however in
practice it doesn't cause any issue with any compiler. However,
thinking that people might be confused with seeing std::unique_ptr and
thinking that we're actually requiring C++11 already, I put the new
types in the "gdb" namespace instead.
For managing xmalloc pointers, this adds a gdb::unique_xmalloc_ptr<T>
"specialization" with a custom xfree deleter.
No actual use of any smart pointer is introduced in this patch.
That'll be done in following patches.
Tested (along with the rest of the series) on:
- NetBSD 5.1 (gcc70 on the compile farm), w/ gcc 4.1.3
- x86-64 Fedora 23, gcc 5.3.1 (gnu++03)
- x86-64 Fedora 23, and gcc 7.0 (gnu++14)
gdb/ChangeLog:
2016-10-18 Pedro Alves <palves@redhat.com>
* common/common-defs.h: Include "gdb_unique_ptr.h".
* common/gdb_unique_ptr.h: New.
2016-10-18 18:42:35 +08:00
|
|
|
|
|
|
|
namespace gdb
|
|
|
|
{
|
2016-11-16 03:54:21 +08:00
|
|
|
/* Define gdb::unique_xmalloc_ptr, a std::unique_ptr that manages
|
Introduce gdb::unique_ptr
Many make_cleanup uses in the code base are best eliminated by using a
"owning" smart pointer to manage ownership of the resource
automatically.
The question is _which_ smart pointer.
GDB currently supports building with a C++03 compiler. We have
std::auto_ptr in C++03, but, as is collective wisdom by now, that's
too easy to misuse, and has therefore been deprecated in C++11 and
finally removed in C++17.
It'd be nice to be able to use std::unique_ptr instead, which is the
modern, safe std::auto_ptr replacement in C++11.
In addition to extra safety -- moving (i.e., transfer of ownership of
the managed pointer between smart pointers) must be explicit --
std::unique_ptr has (among others) one nice feature that std::auto_ptr
doesn't --- ability to specify a custom deleter as template parameter.
In gdb's context, that allows easily creating a smart pointer for
memory allocated with xmalloc -- the smart pointer then knows to
release with xfree instead of delete. This is particularly
interesting when managing objects allocated in C libraries, and also,
for C++-fying parts of GDB that interact with other parts that still
return objects allocated with xmalloc.
Since std::unique_ptr's API is quite nice, and eventually we'd like to
move to C++11, this patch adds a C++03-compatible smart pointer that
exposes the subset of the std::unique_ptr API that we're interested
in. An advantage is that whenever we start requiring C++11, we won't
have to learn a new API. Meanwhile, this allows continuing to support
building with a C++03 compiler.
Since C++03 doesn't support rvalue references (boost gets close to
emulating them, but it's not fully transparent to user code), the
C++03 std::unique_ptr emulation here doesn't try hard to prevent
accidentally moving, which is where most of complication of a more
thorough emulation would be. Instead, we rely on the fact that GDB
will be usually compiled with a C++11 compiler, and use the real
std::unique_ptr in that case to catch such accidental moves. IOW, 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.
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:
- Support for custom (stateless) deleters. (Support for stateful
deleters could be added, if necessary.)
- unique_ptr<T[]> partial specialization (auto_ptr<T> does not know
to use delete[]).
- Support for all of 'ptr != NULL', 'ptr == NULL' and 'if (ptr)'
using the safe bool idiom to emulate C++11's explicit bool
operator.
- There's no nullptr in C++03, so this allows initialization and
assignment from NULL instead (std::auto_ptr allows neither).
- Variable names un-uglified (ie., no leading __ prefix everywhere).
- Formatting made to follow GDB's coding conventions, including
comment style.
- Converting "move" constructors done differently in order to truly
support:
unique_ptr<Derived> func_returning_unique_ptr (.....);
...
unique_ptr<Base> ptr = func_returning_unique_ptr (.....);
At this point, it no longer shares much at all with the original file,
but, that's the history.
See comments in the code to find out more.
I thought of putting the "emulation" / shim in the "std" namespace, so
that when we start requiring C++11 at some point, no actual changes to
users of the smart pointer throughout would be necessary. Putting
things in the std namespace is technically undefined, however in
practice it doesn't cause any issue with any compiler. However,
thinking that people might be confused with seeing std::unique_ptr and
thinking that we're actually requiring C++11 already, I put the new
types in the "gdb" namespace instead.
For managing xmalloc pointers, this adds a gdb::unique_xmalloc_ptr<T>
"specialization" with a custom xfree deleter.
No actual use of any smart pointer is introduced in this patch.
That'll be done in following patches.
Tested (along with the rest of the series) on:
- NetBSD 5.1 (gcc70 on the compile farm), w/ gcc 4.1.3
- x86-64 Fedora 23, gcc 5.3.1 (gnu++03)
- x86-64 Fedora 23, and gcc 7.0 (gnu++14)
gdb/ChangeLog:
2016-10-18 Pedro Alves <palves@redhat.com>
* common/common-defs.h: Include "gdb_unique_ptr.h".
* common/gdb_unique_ptr.h: New.
2016-10-18 18:42:35 +08:00
|
|
|
xmalloc'ed memory. */
|
|
|
|
|
2016-11-16 03:54:21 +08:00
|
|
|
/* The deleter for std::unique_xmalloc_ptr. Uses xfree. */
|
Introduce gdb::unique_ptr
Many make_cleanup uses in the code base are best eliminated by using a
"owning" smart pointer to manage ownership of the resource
automatically.
The question is _which_ smart pointer.
GDB currently supports building with a C++03 compiler. We have
std::auto_ptr in C++03, but, as is collective wisdom by now, that's
too easy to misuse, and has therefore been deprecated in C++11 and
finally removed in C++17.
It'd be nice to be able to use std::unique_ptr instead, which is the
modern, safe std::auto_ptr replacement in C++11.
In addition to extra safety -- moving (i.e., transfer of ownership of
the managed pointer between smart pointers) must be explicit --
std::unique_ptr has (among others) one nice feature that std::auto_ptr
doesn't --- ability to specify a custom deleter as template parameter.
In gdb's context, that allows easily creating a smart pointer for
memory allocated with xmalloc -- the smart pointer then knows to
release with xfree instead of delete. This is particularly
interesting when managing objects allocated in C libraries, and also,
for C++-fying parts of GDB that interact with other parts that still
return objects allocated with xmalloc.
Since std::unique_ptr's API is quite nice, and eventually we'd like to
move to C++11, this patch adds a C++03-compatible smart pointer that
exposes the subset of the std::unique_ptr API that we're interested
in. An advantage is that whenever we start requiring C++11, we won't
have to learn a new API. Meanwhile, this allows continuing to support
building with a C++03 compiler.
Since C++03 doesn't support rvalue references (boost gets close to
emulating them, but it's not fully transparent to user code), the
C++03 std::unique_ptr emulation here doesn't try hard to prevent
accidentally moving, which is where most of complication of a more
thorough emulation would be. Instead, we rely on the fact that GDB
will be usually compiled with a C++11 compiler, and use the real
std::unique_ptr in that case to catch such accidental moves. IOW, 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.
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:
- Support for custom (stateless) deleters. (Support for stateful
deleters could be added, if necessary.)
- unique_ptr<T[]> partial specialization (auto_ptr<T> does not know
to use delete[]).
- Support for all of 'ptr != NULL', 'ptr == NULL' and 'if (ptr)'
using the safe bool idiom to emulate C++11's explicit bool
operator.
- There's no nullptr in C++03, so this allows initialization and
assignment from NULL instead (std::auto_ptr allows neither).
- Variable names un-uglified (ie., no leading __ prefix everywhere).
- Formatting made to follow GDB's coding conventions, including
comment style.
- Converting "move" constructors done differently in order to truly
support:
unique_ptr<Derived> func_returning_unique_ptr (.....);
...
unique_ptr<Base> ptr = func_returning_unique_ptr (.....);
At this point, it no longer shares much at all with the original file,
but, that's the history.
See comments in the code to find out more.
I thought of putting the "emulation" / shim in the "std" namespace, so
that when we start requiring C++11 at some point, no actual changes to
users of the smart pointer throughout would be necessary. Putting
things in the std namespace is technically undefined, however in
practice it doesn't cause any issue with any compiler. However,
thinking that people might be confused with seeing std::unique_ptr and
thinking that we're actually requiring C++11 already, I put the new
types in the "gdb" namespace instead.
For managing xmalloc pointers, this adds a gdb::unique_xmalloc_ptr<T>
"specialization" with a custom xfree deleter.
No actual use of any smart pointer is introduced in this patch.
That'll be done in following patches.
Tested (along with the rest of the series) on:
- NetBSD 5.1 (gcc70 on the compile farm), w/ gcc 4.1.3
- x86-64 Fedora 23, gcc 5.3.1 (gnu++03)
- x86-64 Fedora 23, and gcc 7.0 (gnu++14)
gdb/ChangeLog:
2016-10-18 Pedro Alves <palves@redhat.com>
* common/common-defs.h: Include "gdb_unique_ptr.h".
* common/gdb_unique_ptr.h: New.
2016-10-18 18:42:35 +08:00
|
|
|
template <typename T>
|
|
|
|
struct xfree_deleter
|
|
|
|
{
|
|
|
|
void operator() (T *ptr) const { xfree (ptr); }
|
|
|
|
};
|
|
|
|
|
2017-08-10 21:18:02 +08:00
|
|
|
/* Same, for arrays. */
|
|
|
|
template <typename T>
|
|
|
|
struct xfree_deleter<T[]>
|
|
|
|
{
|
|
|
|
void operator() (T *ptr) const { xfree (ptr); }
|
|
|
|
};
|
|
|
|
|
2016-11-16 03:54:21 +08:00
|
|
|
/* Import the standard unique_ptr to our namespace with a custom
|
|
|
|
deleter. */
|
Introduce gdb::unique_ptr
Many make_cleanup uses in the code base are best eliminated by using a
"owning" smart pointer to manage ownership of the resource
automatically.
The question is _which_ smart pointer.
GDB currently supports building with a C++03 compiler. We have
std::auto_ptr in C++03, but, as is collective wisdom by now, that's
too easy to misuse, and has therefore been deprecated in C++11 and
finally removed in C++17.
It'd be nice to be able to use std::unique_ptr instead, which is the
modern, safe std::auto_ptr replacement in C++11.
In addition to extra safety -- moving (i.e., transfer of ownership of
the managed pointer between smart pointers) must be explicit --
std::unique_ptr has (among others) one nice feature that std::auto_ptr
doesn't --- ability to specify a custom deleter as template parameter.
In gdb's context, that allows easily creating a smart pointer for
memory allocated with xmalloc -- the smart pointer then knows to
release with xfree instead of delete. This is particularly
interesting when managing objects allocated in C libraries, and also,
for C++-fying parts of GDB that interact with other parts that still
return objects allocated with xmalloc.
Since std::unique_ptr's API is quite nice, and eventually we'd like to
move to C++11, this patch adds a C++03-compatible smart pointer that
exposes the subset of the std::unique_ptr API that we're interested
in. An advantage is that whenever we start requiring C++11, we won't
have to learn a new API. Meanwhile, this allows continuing to support
building with a C++03 compiler.
Since C++03 doesn't support rvalue references (boost gets close to
emulating them, but it's not fully transparent to user code), the
C++03 std::unique_ptr emulation here doesn't try hard to prevent
accidentally moving, which is where most of complication of a more
thorough emulation would be. Instead, we rely on the fact that GDB
will be usually compiled with a C++11 compiler, and use the real
std::unique_ptr in that case to catch such accidental moves. IOW, 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.
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:
- Support for custom (stateless) deleters. (Support for stateful
deleters could be added, if necessary.)
- unique_ptr<T[]> partial specialization (auto_ptr<T> does not know
to use delete[]).
- Support for all of 'ptr != NULL', 'ptr == NULL' and 'if (ptr)'
using the safe bool idiom to emulate C++11's explicit bool
operator.
- There's no nullptr in C++03, so this allows initialization and
assignment from NULL instead (std::auto_ptr allows neither).
- Variable names un-uglified (ie., no leading __ prefix everywhere).
- Formatting made to follow GDB's coding conventions, including
comment style.
- Converting "move" constructors done differently in order to truly
support:
unique_ptr<Derived> func_returning_unique_ptr (.....);
...
unique_ptr<Base> ptr = func_returning_unique_ptr (.....);
At this point, it no longer shares much at all with the original file,
but, that's the history.
See comments in the code to find out more.
I thought of putting the "emulation" / shim in the "std" namespace, so
that when we start requiring C++11 at some point, no actual changes to
users of the smart pointer throughout would be necessary. Putting
things in the std namespace is technically undefined, however in
practice it doesn't cause any issue with any compiler. However,
thinking that people might be confused with seeing std::unique_ptr and
thinking that we're actually requiring C++11 already, I put the new
types in the "gdb" namespace instead.
For managing xmalloc pointers, this adds a gdb::unique_xmalloc_ptr<T>
"specialization" with a custom xfree deleter.
No actual use of any smart pointer is introduced in this patch.
That'll be done in following patches.
Tested (along with the rest of the series) on:
- NetBSD 5.1 (gcc70 on the compile farm), w/ gcc 4.1.3
- x86-64 Fedora 23, gcc 5.3.1 (gnu++03)
- x86-64 Fedora 23, and gcc 7.0 (gnu++14)
gdb/ChangeLog:
2016-10-18 Pedro Alves <palves@redhat.com>
* common/common-defs.h: Include "gdb_unique_ptr.h".
* common/gdb_unique_ptr.h: New.
2016-10-18 18:42:35 +08:00
|
|
|
|
|
|
|
template<typename T> using unique_xmalloc_ptr
|
|
|
|
= std::unique_ptr<T, xfree_deleter<T>>;
|
|
|
|
|
2019-05-02 05:28:18 +08:00
|
|
|
/* A no-op deleter. */
|
|
|
|
template<typename T>
|
|
|
|
struct noop_deleter
|
|
|
|
{
|
|
|
|
void operator() (T *ptr) const { }
|
|
|
|
};
|
|
|
|
|
Introduce gdb::unique_ptr
Many make_cleanup uses in the code base are best eliminated by using a
"owning" smart pointer to manage ownership of the resource
automatically.
The question is _which_ smart pointer.
GDB currently supports building with a C++03 compiler. We have
std::auto_ptr in C++03, but, as is collective wisdom by now, that's
too easy to misuse, and has therefore been deprecated in C++11 and
finally removed in C++17.
It'd be nice to be able to use std::unique_ptr instead, which is the
modern, safe std::auto_ptr replacement in C++11.
In addition to extra safety -- moving (i.e., transfer of ownership of
the managed pointer between smart pointers) must be explicit --
std::unique_ptr has (among others) one nice feature that std::auto_ptr
doesn't --- ability to specify a custom deleter as template parameter.
In gdb's context, that allows easily creating a smart pointer for
memory allocated with xmalloc -- the smart pointer then knows to
release with xfree instead of delete. This is particularly
interesting when managing objects allocated in C libraries, and also,
for C++-fying parts of GDB that interact with other parts that still
return objects allocated with xmalloc.
Since std::unique_ptr's API is quite nice, and eventually we'd like to
move to C++11, this patch adds a C++03-compatible smart pointer that
exposes the subset of the std::unique_ptr API that we're interested
in. An advantage is that whenever we start requiring C++11, we won't
have to learn a new API. Meanwhile, this allows continuing to support
building with a C++03 compiler.
Since C++03 doesn't support rvalue references (boost gets close to
emulating them, but it's not fully transparent to user code), the
C++03 std::unique_ptr emulation here doesn't try hard to prevent
accidentally moving, which is where most of complication of a more
thorough emulation would be. Instead, we rely on the fact that GDB
will be usually compiled with a C++11 compiler, and use the real
std::unique_ptr in that case to catch such accidental moves. IOW, 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.
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:
- Support for custom (stateless) deleters. (Support for stateful
deleters could be added, if necessary.)
- unique_ptr<T[]> partial specialization (auto_ptr<T> does not know
to use delete[]).
- Support for all of 'ptr != NULL', 'ptr == NULL' and 'if (ptr)'
using the safe bool idiom to emulate C++11's explicit bool
operator.
- There's no nullptr in C++03, so this allows initialization and
assignment from NULL instead (std::auto_ptr allows neither).
- Variable names un-uglified (ie., no leading __ prefix everywhere).
- Formatting made to follow GDB's coding conventions, including
comment style.
- Converting "move" constructors done differently in order to truly
support:
unique_ptr<Derived> func_returning_unique_ptr (.....);
...
unique_ptr<Base> ptr = func_returning_unique_ptr (.....);
At this point, it no longer shares much at all with the original file,
but, that's the history.
See comments in the code to find out more.
I thought of putting the "emulation" / shim in the "std" namespace, so
that when we start requiring C++11 at some point, no actual changes to
users of the smart pointer throughout would be necessary. Putting
things in the std namespace is technically undefined, however in
practice it doesn't cause any issue with any compiler. However,
thinking that people might be confused with seeing std::unique_ptr and
thinking that we're actually requiring C++11 already, I put the new
types in the "gdb" namespace instead.
For managing xmalloc pointers, this adds a gdb::unique_xmalloc_ptr<T>
"specialization" with a custom xfree deleter.
No actual use of any smart pointer is introduced in this patch.
That'll be done in following patches.
Tested (along with the rest of the series) on:
- NetBSD 5.1 (gcc70 on the compile farm), w/ gcc 4.1.3
- x86-64 Fedora 23, gcc 5.3.1 (gnu++03)
- x86-64 Fedora 23, and gcc 7.0 (gnu++14)
gdb/ChangeLog:
2016-10-18 Pedro Alves <palves@redhat.com>
* common/common-defs.h: Include "gdb_unique_ptr.h".
* common/gdb_unique_ptr.h: New.
2016-10-18 18:42:35 +08:00
|
|
|
} /* namespace gdb */
|
|
|
|
|
2019-06-05 05:40:54 +08:00
|
|
|
/* Dup STR and return a unique_xmalloc_ptr for the result. */
|
|
|
|
|
|
|
|
static inline gdb::unique_xmalloc_ptr<char>
|
|
|
|
make_unique_xstrdup (const char *str)
|
|
|
|
{
|
|
|
|
return gdb::unique_xmalloc_ptr<char> (xstrdup (str));
|
|
|
|
}
|
|
|
|
|
2021-06-05 06:00:33 +08:00
|
|
|
/* Dup the first N characters of STR and return a unique_xmalloc_ptr
|
|
|
|
for the result. The result is always \0-terminated. */
|
|
|
|
|
|
|
|
static inline gdb::unique_xmalloc_ptr<char>
|
|
|
|
make_unique_xstrndup (const char *str, size_t n)
|
|
|
|
{
|
|
|
|
return gdb::unique_xmalloc_ptr<char> (xstrndup (str, n));
|
|
|
|
}
|
|
|
|
|
2023-10-10 00:59:12 +08:00
|
|
|
/* An overload of operator+= for adding gdb::unique_xmalloc_ptr<char> to a
|
2022-02-21 22:07:45 +08:00
|
|
|
std::string. */
|
|
|
|
|
|
|
|
static inline std::string &
|
|
|
|
operator+= (std::string &lhs, const gdb::unique_xmalloc_ptr<char> &rhs)
|
|
|
|
{
|
|
|
|
return lhs += rhs.get ();
|
|
|
|
}
|
|
|
|
|
|
|
|
/* An overload of operator+ for adding gdb::unique_xmalloc_ptr<char> to a
|
|
|
|
std::string. */
|
|
|
|
|
|
|
|
static inline std::string
|
|
|
|
operator+ (const std::string &lhs, const gdb::unique_xmalloc_ptr<char> &rhs)
|
|
|
|
{
|
|
|
|
return lhs + rhs.get ();
|
|
|
|
}
|
|
|
|
|
2019-01-28 03:51:36 +08:00
|
|
|
#endif /* COMMON_GDB_UNIQUE_PTR_H */
|