diff options
Diffstat (limited to 'gdb/common')
-rw-r--r-- | gdb/common/byte-vector.h | 62 | ||||
-rw-r--r-- | gdb/common/def-vector.h | 36 | ||||
-rw-r--r-- | gdb/common/default-init-alloc.h | 67 |
3 files changed, 165 insertions, 0 deletions
diff --git a/gdb/common/byte-vector.h b/gdb/common/byte-vector.h new file mode 100644 index 0000000..c17b14d --- /dev/null +++ b/gdb/common/byte-vector.h @@ -0,0 +1,62 @@ +/* Copyright (C) 2017 Free Software Foundation, Inc. + + 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/>. */ + +#ifndef COMMON_BYTE_VECTOR_H +#define COMMON_BYTE_VECTOR_H + +#include "common/def-vector.h" + +namespace gdb { + +/* byte_vector is a gdb_byte std::vector with a custom allocator that + unlike std::vector<gdb_byte> does not zero-initialize new elements + by default when the vector is created/resized. This is what you + usually want when working with byte buffers, since if you're + creating or growing a buffer you'll most surely want to fill it in + with data, in which case zero-initialization would be a + pessimization. For example: + + gdb::byte_vector buf (some_large_size); + fill_with_data (buf.data (), buf.size ()); + + On the odd case you do need zero initialization, then you can still + call the overloads that specify an explicit value, like: + + gdb::byte_vector buf (some_initial_size, 0); + buf.resize (a_bigger_size, 0); + + (Or use std::vector<gdb_byte> instead.) + + Note that unlike std::vector<gdb_byte>, function local + gdb::byte_vector objects constructed with an initial size like: + + gdb::byte_vector buf (some_size); + fill_with_data (buf.data (), buf.size ()); + + usually compile down to the exact same as: + + std::unique_ptr<byte[]> buf (new gdb_byte[some_size]); + fill_with_data (buf.get (), some_size); + + with the former having the advantage of being a bit more readable, + and providing the whole std::vector API, if you end up needing it. +*/ +using byte_vector = gdb::def_vector<gdb_byte>; + +} /* namespace gdb */ + +#endif /* COMMON_DEF_VECTOR_H */ diff --git a/gdb/common/def-vector.h b/gdb/common/def-vector.h new file mode 100644 index 0000000..ab9331f --- /dev/null +++ b/gdb/common/def-vector.h @@ -0,0 +1,36 @@ +/* Copyright (C) 2017 Free Software Foundation, Inc. + + 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/>. */ + +#ifndef COMMON_DEF_VECTOR_H +#define COMMON_DEF_VECTOR_H + +#include <vector> +#include "common/default-init-alloc.h" + +namespace gdb { + +/* A vector that uses an allocator that default constructs using + default-initialization rather than value-initialization. The idea + is to use this when you don't want zero-initialization of elements + of vectors of trivial types. E.g., byte buffers. */ + +template<typename T> using def_vector + = std::vector<T, gdb::default_init_allocator<T>>; + +} /* namespace gdb */ + +#endif /* COMMON_DEF_VECTOR_H */ diff --git a/gdb/common/default-init-alloc.h b/gdb/common/default-init-alloc.h new file mode 100644 index 0000000..4fb852f --- /dev/null +++ b/gdb/common/default-init-alloc.h @@ -0,0 +1,67 @@ +/* Copyright (C) 2017 Free Software Foundation, Inc. + + 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/>. */ + +#ifndef COMMON_DEFAULT_INIT_ALLOC_H +#define COMMON_DEFAULT_INIT_ALLOC_H + +namespace gdb { + +/* An allocator that default constructs using default-initialization + rather than value-initialization. The idea is to use this when you + don't want to default construct elements of containers of trivial + types using zero-initialization. */ + +/* Mostly as implementation convenience, this is implemented as an + adapter that given an allocator A, overrides 'A::construct()'. 'A' + defaults to std::allocator<T>. */ + +template<typename T, typename A = std::allocator<T>> +class default_init_allocator : public A +{ +public: + /* Pull in A's ctors. */ + using A::A; + + /* Override rebind. */ + template<typename U> + struct rebind + { + /* A couple helpers just to make it a bit more readable. */ + typedef std::allocator_traits<A> traits_; + typedef typename traits_::template rebind_alloc<U> alloc_; + + /* This is what we're after. */ + typedef default_init_allocator<U, alloc_> other; + }; + + /* Make the base allocator's construct method(s) visible. */ + using A::construct; + + /* .. and provide an override/overload for the case of default + construction (i.e., no arguments). This is where we construct + with default-init. */ + template <typename U> + void construct (U *ptr) + noexcept (std::is_nothrow_default_constructible<U>::value) + { + ::new ((void *) ptr) U; /* default-init */ + } +}; + +} /* namespace gdb */ + +#endif /* COMMON_DEFAULT_INIT_ALLOC_H */ |