summaryrefslogtreecommitdiffstats
path: root/noinitvector.hh
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 09:34:30 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 09:34:30 +0000
commit4fc2f55f761d71aae1f145d5aa94ba929cc39676 (patch)
tree5c1e1db3b46dd4edbe11f612d93cb94b96891ce3 /noinitvector.hh
parentInitial commit. (diff)
downloaddnsdist-4fc2f55f761d71aae1f145d5aa94ba929cc39676.tar.xz
dnsdist-4fc2f55f761d71aae1f145d5aa94ba929cc39676.zip
Adding upstream version 1.7.3.upstream/1.7.3upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--noinitvector.hh67
1 files changed, 67 insertions, 0 deletions
diff --git a/noinitvector.hh b/noinitvector.hh
new file mode 100644
index 0000000..cc7efc3
--- /dev/null
+++ b/noinitvector.hh
@@ -0,0 +1,67 @@
+#pragma once
+
+#include <memory>
+#include <new>
+#include <utility>
+#include <vector>
+
+// based on boost::core::noinit_adaptor
+// The goal is to avoid initialization of the content of a container,
+// because setting several kB of uint8_t to 0 has a real cost if you
+// do 100k times per second.
+template<class Allocator>
+struct noinit_adaptor: Allocator
+{
+ template<class U>
+ struct rebind {
+ typedef noinit_adaptor<typename std::allocator_traits<Allocator>::template
+ rebind_alloc<U> > other;
+ };
+
+ noinit_adaptor(): Allocator() { }
+
+ template<class U>
+ noinit_adaptor(U&& u) noexcept : Allocator(std::forward<U>(u)) { }
+
+ template<class U>
+ noinit_adaptor(const noinit_adaptor<U>& u) noexcept : Allocator(static_cast<const U&>(u)) { }
+
+ template<class U>
+ void construct(U* p) {
+ ::new((void*)p) U;
+ }
+
+ template<class U, class V, class... Args>
+ void construct(U* p, V&& v, Args&&... args) {
+ ::new((void*)p) U(std::forward<V>(v), std::forward<Args>(args)...);
+ }
+
+ template<class U>
+ void destroy(U* p) {
+ p->~U();
+ }
+};
+
+template<class T, class U>
+inline bool operator==(const noinit_adaptor<T>& lhs,
+ const noinit_adaptor<U>& rhs) noexcept
+{
+ return static_cast<const T&>(lhs) == static_cast<const U&>(rhs);
+}
+
+template<class T, class U>
+inline bool operator!=(const noinit_adaptor<T>& lhs,
+ const noinit_adaptor<U>& rhs) noexcept
+{
+ return !(lhs == rhs);
+}
+
+template<class Allocator>
+inline noinit_adaptor<Allocator> noinit_adapt(const Allocator& a) noexcept
+{
+ return noinit_adaptor<Allocator>(a);
+}
+
+template<class T> using NoInitVector = std::vector<T, noinit_adaptor<std::allocator<T>>>;
+
+using PacketBuffer = NoInitVector<uint8_t>;